在此分别总结先序,中序,后序的结点输出顺序。
先序: 1.访问根结点
2.访问左子树
3.访问右子树
中序:1.访问左子树
2.访问根结点
3.访问右子树
访问左子树。【先访问左子树中的左子树,再访问左子树中的右子树。】直到访问到叶子结点后输出。
输出根。
访问右子树。【先访问右子树中的左子树,再访问右子树中的右子树。】直到访问到叶子结点后输出。
后序:1.访问左子树
2.访问右子树
3.访问根
访问左子树。【先访问左子树中的左子树,再访问左子树中的右子树】。直到访问到叶子结点后输出。
访问右子树。【先访问右子树中的左子树,再访问右子树中的右子树】。直到访问到叶子结点后输出。
再返回访问根,并输出。
如何用栈实现递三种遍历树的算法
1)前序遍历
void preorder_nonrecursive(Bitree T) /* 先序遍历二叉树的非递归算法 */
{
initstack(S);
push(S,T); /* 根指针进栈 */
while(!stackempty(S)) {
while(gettop(S,p)&&p) { /* 向左走到尽头 */
visit(p); /* 每向前走一步都访问当前结点 */
push(S,p->lchild);
}
pop(S,p);
if(!stackempty(S)) { /* 向右走一步 */
pop(S,p);
push(S,p->rchild);
}
}
}
2)中序遍历
void inorder_nonrecursive(Bitree T)
{
initstack(S); /* 初始化栈 */
push(S, T); /* 根指针入栈 */
while (!stackempty(S)) {
while (gettop(S, p) && p) /* 向左走到尽头 */
push(S, p->lchild);
pop(S, p); /* 空指针退栈 */
if (!stackempty(S)) {
pop(S, p);
visit(p); /* 访问当前结点 */
push(S, p->rchild); /* 向右走一步 */
}
}
}
3)后序遍历
typedef struct {
BTNode* ptr;
enum {0,1,2} mark;
} PMType; /* 有mark域的结点指针类型 */
void postorder_nonrecursive(BiTree T) /*
后续遍历二叉树的非递归算法 */
{
EMType a;
initstack(S); /* S的元素为EMType类型 */
push (S,{T,0}); /* 根结点入栈 */
while(!stackempty(S)) {
pop(S,a);
switch(a.mark)
{
case 0:
push(S,{a.ptr,1}); /* 修改mark域 */
if(a.ptr->lchild)
push(S,{a.ptr->lchild,0}); /* 访问左子树 */
break;
case 1:
push(S,{a.ptr,2}); /* 修改mark域 */
if(a.ptr->rchild)
push(S,{a.ptr->rchild,0}); /* 访问右子树 */
break;
case 2:
visit(a.ptr); /* 访问结点 */
}
}
}