非递归二叉树前中后序遍历

以前经常说:

系统栈爆了怎么办?

手写啊!!

然而并没有写过一次

这次数据结构课介绍了非递归的二叉树遍历算法,后序还没讲,先写了再说

先序遍历:

1.我的直观想法是先把右子树压进去,再把左子树压进去

2.然而书上给的做法有点不一样,是先压左子树压到底,弹出的时候把当前的右子树给压进去。事实上在先序遍历上来说这两种做法没什么区别,我的想法相当于在压左子树之前就直接先把右子树压进去了

中序遍历:

中序遍历的时候我的做法不是那么管用了,因为先序遍历根节点最先访问,而中序需要左子树弹回来才能访问根节点,所以必须得用类似上面做法2的一样的思路

后序遍历:

可以和先序遍历一样一次性把右左子树压进去,在访问根节点前判一下上一个访问的是不是根节点的左右儿子,也就是说是不是从访问完左右儿子之后弹回来的,或者根本没有左右儿子,满足两种情况之一才能将这个点弹出来并访问,同时更新pre为这个根节点

void preOrder1(BiTree root) {
    stack <BiTree> s;
    BiTree p = root;
    while (p != NULL || !s.empty()) {
        while (p != NULL) {
            visit(p);
            s.push(p);  //prepare the traversal for the p's right child
            p = p -> lchild;
        }
        if (!s.empty()) {
            p = s.top();    //get the node
            s.pop();
            p = p -> rchild;    // turn to right child
        }
    }
}

void preOrder2(BiTree root) {
    stack <BiTree> s;
    BiTree p = root;
    while (!s.empty()) {
        vist(p = s.top());
        s.pop();
        if (p -> rchild != NULL)
            s.push(p -> rchild);
        if (p -> lchild != NULL)
            s.push(p -> lchild);
    }
}

void inOrder(BiTree root) {
    stack <BiTree> s;
    BiTree p = root;
    while (p != NULL || !s.empty()) {
        while (p != NULL) {
            s.push(p);  //prepare the traversal for the p's right child
            p = p -> lchild;
        }
        if (!s.empty()) {
            visit(p = s.top());
            s.pop();
            push(s.rchild);
        }
    }
}

void postOrder(BiTree root) {
    stack <BiTree> s;
    BiTree p = root, pre = NULL;
    s.push(root);
    while (!s.empty()) {
        p = s.top();
        if ((p -> lchild == NULL && p -> rchild == NULL) || (pre != NULL && (pre == p -> lchild || pre == p -> rchild))) {  // come from child node
            visit(p);
            s.pop();
            pre = p;
        }
        else {
            if (p -> rchild != NULL)
                s.push(p -> rchild);
                if (p -> lchild != NULL)
                    s.push(p -> lchild);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值