二叉树的非递归遍历

一、前序遍历。比较简单。

  1. 如果根非空,进栈;
  2. 如果栈非空,访问栈顶元素,栈顶元素为p,出栈;
  3. 如果p的右孩非空,右孩进栈;
  4. 如果p的左孩非空,左孩进栈;
  5. 循环2,3,4。
源码:
void preOrderNoRecursion(BinaryTreeNode* root){
    stack<BinaryTreeNode*> visitStack;
    if(root!=NULL)
        visitStack.push(root);
    while(!visitStack.empty()){
        BinaryTreeNode* top = visitStack.top();
        visitStack.pop();
        cout<<top->val<<" ";
        if(top->right != NULL)
            visitStack.push(top->right);
        if(top->left != NULL)
            visitStack.push(top->left);
    }
}

二、中序遍历。思路: 若其左孩子不为空,则将P入栈并将P的左孩子置为当前的P,然后对当前结点P再进行相同的处理;直到P为NULL并且栈为空则遍历结束;若其左孩子为空,则取栈顶元素并进行出栈操作,访问该栈顶结点,然后将当前的P置为栈顶结点的右孩子;直到P为NULL并且栈为空则遍历结束。
  1. 考察指针v指向根,非空,则进栈;
  2. 如果v的左孩非空,左孩进栈,直到左孩为空;
  3. 访问栈顶元素,栈顶元素为p,p出栈;
  4. 如果p右孩非空,v指向p的右孩。
  5. 循环1, 2,3,4。
源码:
void inOrderNoRecursion(BinaryTreeNode* root){
    BinaryTreeNode* curVisit = root;
    stack<BinaryTreeNode *> noVisit;
    while(curVisit!=NULL || !noVisit.empty()){
        while(curVisit!=NULL){
            noVisit.push(curVisit);
            curVisit = curVisit->left;
        }
        if(!noVisit.empty()){
            BinaryTreeNode* top = noVisit.top();
            noVisit.pop();
            cout<<top->val<<" ";
            curVisit = top->right;
        }
    }
}

三、后序遍历。算法思想:因为后序遍历是左右根。当用栈来存储节点,必须分清楚返回根节点时,是从左子树返回,还是从右子树返回的。所以使用一个辅助指针来指向起最近访问过的节点。也可以在节点中增加一个标志域,记录是否已被访问过(因为需要更改二叉树的数据结构,此处不用)。还有双栈法。
代码如下:
void postOrderNoRecursion(BinaryTreeNode* root){
    BinaryTreeNode *curVisit=root, *haveVisit=NULL;
    stack<BinaryTreeNode *> noVisit;
    while(curVisit!=NULL || !noVisit.empty()){
        while(curVisit!=NULL){
            noVisit.push(curVisit);
            curVisit = curVisit->left;
        }
        BinaryTreeNode* top = noVisit.top();
        if(top->right==NULL || top->right==haveVisit){
            cout<<top->val<<" ";
            noVisit.pop();
            haveVisit = top;
        }else{
            curVisit = top->right;
        }
    }
}
双栈法代码如下:
void postOrderNoRecursionTwoStack(BinaryTreeNode *root){
    stack<BinaryTreeNode *> stack1, stack2;
    BinaryTreeNode* curVisit=root;
    if(curVisit!=NULL)
        stack1.push(curVisit);
    while(!stack1.empty()){
        curVisit = stack1.top();
        stack1.pop();
        stack2.push(curVisit);
        if(curVisit->left!=NULL)
            stack1.push(curVisit->left);
        if(curVisit->right != NULL)
            stack1.push(curVisit->right);
    }
    while(!stack2.empty()){
        curVisit = stack2.top();
        cout<<curVisit->val<<" ";
        stack2.pop();
    }
}

四、整个源代码,包括递归。
#include <iostream>
#include <stack>
using namespace std;

struct BinaryTreeNode{
    int val;
    struct BinaryTreeNode* left;
    struct BinaryTreeNode* right;
    BinaryTreeNode(int val):val(val), left(NULL), right(NULL) {}
};

//前序遍历递归
void preOrderRecursion(BinaryTreeNode* root){
    if(root!=NULL)
        cout << root->val <<" ";
    if(root->left != NULL)
        preOrderRecursion(root->left);
    if(root->right != NULL)
        preOrderRecursion(root->right);
}

//前序遍历非递归
void preOrderNoRecursion(BinaryTreeNode* root){
    stack<BinaryTreeNode*> visitStack;
    if(root!=NULL)
        visitStack.push(root);
    while(!visitStack.empty()){
        BinaryTreeNode* top = visitStack.top();
        visitStack.pop();
        cout<<top->val<<" ";
        if(top->right != NULL)
            visitStack.push(top->right);
        if(top->left != NULL)
            visitStack.push(top->left);
    }
}

//中序遍历递归
void inOrderRecursion(BinaryTreeNode* root){
    if(root==NULL)
        return ;
    if(root->left!=NULL)
        inOrderRecursion(root->left);
    cout<<root->val<<" ";
    if(root->right!=NULL)
        inOrderRecursion(root->right);
}

//中序遍历非递归
void inOrderNoRecursion(BinaryTreeNode* root){
    BinaryTreeNode* curVisit = root;
    stack<BinaryTreeNode *> noVisit;
    while(curVisit!=NULL || !noVisit.empty()){
        while(curVisit!=NULL){
            noVisit.push(curVisit);
            curVisit = curVisit->left;
        }
        if(!noVisit.empty()){
            BinaryTreeNode* top = noVisit.top();
            noVisit.pop();
            cout<<top->val<<" ";
            curVisit = top->right;
        }
    }
}

//后序遍历递归
void postOrderRecursion(BinaryTreeNode* root){
    if(root==NULL)
        return ;
    if(root->left != NULL )
        postOrderRecursion(root->left);
    if(root->right != NULL)
        postOrderRecursion(root->right);
    cout<<root->val<<" ";
}

//后序遍历非递归
void postOrderNoRecursion(BinaryTreeNode* root){
    BinaryTreeNode *curVisit=root, *haveVisit=NULL;
    stack<BinaryTreeNode *> noVisit;
    while(curVisit!=NULL || !noVisit.empty()){
        while(curVisit!=NULL){
            noVisit.push(curVisit);
            curVisit = curVisit->left;
        }
        BinaryTreeNode* top = noVisit.top();
        if(top->right==NULL || top->right==haveVisit){
            cout<<top->val<<" ";
            noVisit.pop();
            haveVisit = top;
        }else{
            curVisit = top->right;
        }
    }
}

//后序遍历非递归,双栈法
void postOrderNoRecursionTwoStack(BinaryTreeNode *root){
    stack<BinaryTreeNode *> stack1, stack2;
    BinaryTreeNode* curVisit=root;
    if(curVisit!=NULL)
        stack1.push(curVisit);
    while(!stack1.empty()){
        curVisit = stack1.top();
        stack1.pop();
        stack2.push(curVisit);
        if(curVisit->left!=NULL)
            stack1.push(curVisit->left);
        if(curVisit->right != NULL)
            stack1.push(curVisit->right);
    }
    while(!stack2.empty()){
        curVisit = stack2.top();
        cout<<curVisit->val<<" ";
        stack2.pop();
    }
}

int main(){
    BinaryTreeNode *node1 = new BinaryTreeNode(5);
    BinaryTreeNode *node2 = new BinaryTreeNode(6);
    BinaryTreeNode *node3 = new BinaryTreeNode(7);
    BinaryTreeNode *node4 = new BinaryTreeNode(8);
    node1->right = node2;
    node2->right = node3;
    node3->left = node4;
    preOrderRecursion(node1);
    cout<< endl;
    preOrderNoRecursion(node1);
    cout<<endl;
    inOrderRecursion(node1);
    cout<<endl;
    inOrderNoRecursion(node1);
    cout<<endl;
    postOrderRecursion(node1);
    cout<<endl;
    postOrderNoRecursion(node1);
    cout<<endl;
    postOrderNoRecursionTwoStack(node1);
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值