【囤】二叉树遍历的非递归实现

a.先序遍历的非递归算法

思路

假设:T指向要遍历的二叉树的根,若T !=NULL 对于非递归算法,引入栈模拟递归工作栈,初始栈为空。
问题:如何用栈来保存信息,使得在先序遍历过左子树后,能利用栈顶信息获取T的右子树的根指针?
方法:访问T->data后,将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,再先序遍历T的右子树。

代码实现

void Preorder_I(BiTree T, void (*visit)(TelemType &e)){  
    Stack *S;
    initStack(S);
    t=T;
    while(!(t == NULL && StackEmpty(S)) {
        while(t){  
            visit(t->data); 
            push(S,t); 
            t=t->lchild;
        }
        if (StackEmpty(S)) 
            return;   // 栈空时结束
        else {  
            t = Pop(S);
            t=t->rchild;
        }
    } // while
}// Preorder_I   

b.中序遍历的非递归算法

思路

假设:T是指向要遍历的二叉树的根,中序遍历要求在遍历完左子树后,访问根,再遍历右子树。
问题:如何用栈来保存信息,使得在中序遍历过左子树后,利用栈顶信息获取T指针?
方法:先将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,访问T->data,再中序遍历T的右子树。 

代码实现

void Inorder_I(BiTree T, void (*visit)(TelemType &e)){
    Stack* S;
    t = T;
    while (!(t == NULL && StackEmpty(S)) {
        while (t) {    
            push(S, t);
            t = t->lchild;
        }
        if (StackEmpty(S)) return;   // 栈空时结束
        else {
            t = Pop(S);
            visit(t->data);
            t = t->rchild;
        }
    } // while
}// Inorder_I

c.后续遍历的非递归算法

思路

假设:T指向要遍历的二叉树的根,后序遍历要求在遍历完左右子树后,再访问根。
问题:需要判断根结点的左右子树是否均遍历过。
方法:可采用标记法,结点入栈时,配一个标志tag一同入栈(0:遍历左子树前的现场保护,1:遍历右子树前的现场保护)。
首先将T和tag(为0)入栈,遍历左子树;返回后,修改栈顶tag(为1),遍历右子树;最后访问根结点。


代码实现

void Postorder_I(BiTree T, void (*visit)(TelemType &e)){
    Stack* S;
    t = T;
    while (!(t == NULL && StackEmpty(S))){
        if (t) {
            push(S, (t, 1));
            t = t->lchild;
        }
        else {
            t = top(s).link;
            sign = top(s).tag;
            pop(s);
            if (sign == 1) {
                push(S, (t, 2));
                t = t->rchild;
            }
            else {
                Visit(t->data);
                t = NULL;
            }
        }
    } // while
}// Postorder_I






全部评论

相关推荐

06-10 23:36
已编辑
首都经济贸易大学 C++
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务