您的位置:首页 > 其它

CLRS 10.4有根树的表示

2015-12-05 10:21 218 查看
10.4-1



10.4-2、10.4-3

给出先中后序的递归和非递归代码

#include <iostream>
#include <stack>
using std::cout;
using std::endl;
using std::stack;

struct binTree
{
int key;
binTree *left;
binTree *right;
binTree(int x):key(x),left(NULL),right(NULL){}
};

void preorder(binTree *root)        //先序遍历
{
if(root != NULL)
{
cout << root->key << ' ';
preorder(root->left);
preorder(root->right);
}
}

void inorder(binTree *root)     //中序遍历
{
if(root != NULL)
{
inorder(root->left);
cout << root->key << ' ';
inorder(root->right);
}
}

void postorder(binTree *root)   //后序遍历
{
if(root != NULL)
{
postorder(root->left);
postorder(root->right);
cout << root->key << ' ';
}
}

void non_recursive_preorder(binTree *root)
{
stack<binTree *> ptr;
binTree *p = root;
while(p || !ptr.empty())
{
while(p)        //p非空,输出然后继续向左子树走
{
cout << p->key << ' ';
ptr.push(p);
p = p->left;
}
if(!ptr.empty())    //左子树空但栈不空,得到左子树的根,然后向右子树走
{
p = ptr.top();
ptr.pop();
p = p->right;
}
}
}

void non_recursive_inorder(binTree *root)
{
stack<binTree *> ptr;
binTree *p = root;
while(p || !ptr.empty())
{
while(p)        //一直找到最左孩子
{
ptr.push(p);
p = p->left;
}
if(!ptr.empty())    //出栈,然后向右子树走
{
p = ptr.top();
cout << p->key << ' ';
ptr.pop();
p = p->right;
}
}
}

void non_recursive_postorder(binTree *root)
{
stack<binTree *> ptr;
binTree *cur;
binTree *pre = NULL;
ptr.push(root);
while(!ptr.empty())
{
cur = ptr.top();
//当前结点无左右孩子或者左右孩子已经访问过了,输出当前结点
if((cur->left == NULL && cur->right == NULL) || pre && (pre == cur->left || pre == cur->right))
{
cout << cur->key << ' ';
ptr.pop();
pre = cur;
}
else    //当前结点右子树和左子树分别压入栈
{
if(cur->right != NULL)
ptr.push(cur->right);
if(cur->left != NULL)
ptr.push(cur->left);
}
}
}


10.4-4

和二叉树遍历没什么区别,见上。

10.4-5

采用类似中序遍历的方法,每个结点有三个指针,分别指向父结点,左右孩子结点。同时标记左右结点是否访问过,如果都访问过了,则说明当前节点的子树已经访问过,因此向上走。如果左右都没访问过,则向左一路到底。如果左边访问过了,右边没访问过,则向右移一位,再一路向左到底。

#include <iostream>
using std::cout;
using std::endl;

struct binTree
{
int key;
binTree *left;
binTree *right;
binTree *parent;
binTree(int x):key(x),left(NULL),right(NULL),parent(NULL){}
};

void non_recursive_traverse(binTree *root)
{
binTree *p = root;
bool left = false, right = false;   //判断当前结点的左孩子和右孩子是否已经访问过
while(!(p == root && left && right))//访问到root结点,退出
{
if(left && right)               //如果左右孩子都访问过,则向上走
{
left = false;
right = false;
if(p->parent->left == p)    //当前是父结点的左孩子
left = true;
if(p->parent->right == p)
{
left = true;
right = true;
}
p = p->parent;
}
else if (!right)                //跳转到右边
{
while(p->left != NULL && !left) //如果左边也没访问过,则一直向左走到底
p = p->left;
cout << p->key << ' ';
if(p->right != NULL)       //如果右边有结点,则向右走
{
p = p->right;
left = false;
right = false;
}
else                       //如果右边没有结点,就向上走
{
left = false;
right = false;
if(p->parent->left == p)
left = true;
if(p->parent->right == p)
{
left = true;
right = true;
}
p = p->parent;
}
}
}
}


10.4-6

布尔变量判断此结点是否是最右结点,若是则指向父结点,不是则指向右兄弟,另外一个指针则指向左孩子。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: