二叉树的非递归遍历

typedef struct TreeNode{
    int value;
    struct TreeNode *lchild, *rchild;
}TreeNode;

//二叉树的先序遍历非递归
void PreOrderTraverse(TreeNode *root){
    if(root == NULL)
        return;
    TreeNode *pNode;
    stack<TreeNode*> s;
    s.push(root);
    while(!s.empty()){
        pNode = s.top();
        cout<<pNode->value<<endl;
        //当前节点访问完后出栈
        s.pop();
        //先让右子树进栈,后访问右子树
        if(pNode->rchild != NULL)
            s.push(pNode->rchild);
        //右子树在栈顶,保证下次访问先访问左子树
        if(pNode->lchild != NULL)
            s.push(pNode->lchild);
    }
}

//二叉树的中序遍历非递归
void InOrderTraverse(TreeNode *root){
    if(root == NULL)
        return;
    TreeNode *pNode = root;
    stack<TreeNode*> s;
    //思路就是每次遍历到最左边的孩子,然后依次出栈访问
    //然后对每个出栈的节点对其右孩子为根节点最上面同样的操作(遍历到最左边,再依次退栈)
    while(pNode!=NULL||!s.empty())
    {
        while(pNode!=NULL)
        {
            s.push(pNode);
            pNode=pNode->lchild;
        }
        if(!s.empty())
        {
            //栈里的所有元素可以视为左孩子
            pNode=s.top();
            cout<<pNode->value<<endl;
            //最重要的就是这个出栈,出栈可以视为这样
            //该栈顶节点左孩子访问出栈,该节点访问后出栈,然后对该节点的右孩子做中序遍历,直至右子树中序访问完毕
            //访问该栈顶节点的祖先节点(也就是栈顶的后一个元素),再重复上述操作(对该祖先节点的右孩子做中序遍历,直至该祖先节点的右子树访问完毕)
            s.pop();
            pNode=pNode->rchild;
        }
    }
}


//二叉树的后序遍历非递归
void PostOrderTraverse(TreeNode *root){
    if(root == NULL)
        return;
    stack<TreeNode*> s;
    TreeNode *pNode = root, *pre;
    //思路就是每个节点都按照右中左的顺序入栈
    //然后出栈有两种情况:
    //    1.第一个出栈的肯定为叶子,无论是左右叶子
    //    2.如果栈顶不是叶子节点,则往下深度搜索
    //第二种情况会出现一种问题,如果这个节点的左右子树已经被访问了
    //如果不加以区分,这个节点的左右子树还会入栈,造成重复访问
    // 这个节点的祖先节点也不能正确的被访问(因为后序遍历是从下往上的)
    //设置pre为上一个被访问的节点,
    s.push(pNode);
    while (!s.empty()) {
        pNode = s.top();
        if (pNode->lchild == NULL && pNode->rchild == NULL) {   //当pNode为叶子时
            cout<<pNode->value<<endl;
            s.pop();
            pre = pNode;
        } else if (pNode->lchild == pre || pNode->rchild == pre) {  //当pNode的左孩子或右孩子被访问后
            cout<<pNode->value<<endl;
            s.pop();
            pre = pNode;
        } else{
            if (pNode->rchild != NULL) {
               s.push(pNode->rchild);
            }
            if (pNode->lchild != NULL) {
                s.push(pNode->lchild);
            }
        }
    }
}


//二叉树的层次遍历非递归
void LevelOrderTraverse(TreeNode *root){
    if(root == NULL)
        return;
    TreeNode *p;
    queue<TreeNode*> q;
    q.push(root);
    while (!q.empty()) {
        p = q.front();
        q.pop();
        cout<<p->value<<endl;
        if (p->lchild)
            q.push(p->lchild);
        if (p->rchild)
            q.push(p->rchild);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值