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

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






全部评论

相关推荐

03-26 13:04
已编辑
电子科技大学 算法工程师
xiaowl:你这个简历“条目上”都比较有深度性,但是实际上面试官又没法很好的评估你是怎么达到很多看上去很厉害的结果的。要避免一些看上去很厉害的包装,比如高效的内存复用策略的表达,如果仅是简单的一些内存共享机制,而且面试上也没有深挖的空间,就不要这样表达。比如,工程化模式本质上可能就是定义了一些abstract class,那也就没特别多值得讲的内容。建议简历上应该侧重那些你花了大量时间和精力解决、研究的问题,不要过分追求“丰富”,而是关注在技术深入度、问题解决能力的表现上。
没有实习经历,还有机会进...
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

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