二叉树的建立,以及非递归遍历

关于二叉树的建立,根据前序和中序,建立二叉树。并且总结关于二叉树前序,中序以及后序的非递归遍历。

1、二叉树的建立

利用递归的思想建立二叉树,如pre[]={8,11,9,3,13,6,15,12,5,7}; mid[]={3,9,13,11,6,15,8,5,12,7}分别代表前序和中序的遍历结果。前序结果中的第一个元素为8,为根节点,中序遍历中mid[0]~mid[5]是8的左子树,左子树的根节点为11,mid[7]~mid[9]为右子树,其根节点为12。建立以8为根的二叉树,就可以转换为建立以11为根的节点8的左子树,和以12为根的节点8的右子树。通过递归调用,构建二叉树。

2、二叉树的非递归前序遍历

前序遍历优先访问根节点,在访问左子树的根节点,在右子树的根节点。访问顺序为根->左孩子->右孩子。利用栈来存储节点,每遇到一个节点,则提取数据。

  1. 设置根节点为当前节点cur,不为空入栈;
  2. 左孩子是否为空,不为空则持续入栈,提取数据,更新当前节点为root。为空则出栈,更新出栈元素的右孩子为当前节点;
  3. 结束条件,栈为空。

3、二叉树的非递归中序遍历

中序遍历的顺序为,左孩子->根节点->右孩子。

  1. 设置根节点为当前节点cur,不为空入栈;
  2. 左孩子是否为空,不为空,入栈,并更新左孩子为当前节点,入栈直至为空;
  3. 当前节点为空,出栈;提取数据,更新右孩子为当前节点。
  4. 结束条件,栈为空。

4、二叉树的非递归后序遍历

后序遍历的顺序为,左孩子->右孩子->根节点。需要设置一个最近的遍历节点,以判断右孩子是否已遍历。

  1. 设置根节点为当前节点cur,不为空则入栈;
  2. 左孩子是否为空,不为空,则入栈,并更新左孩子为当前节点,入栈直至为空;
  3. 当前节点为空,提取头结点为当前节点;判断右孩子为空,或者右孩子已访问,则提取数据,出栈,更新previsited;
  4. 若右孩子不为空,且未访问,则设置右孩子为当前节点;
  5. 结束条件,栈为空。
#include<iostream>
#include<stack>

using namespace std;

struct node{
    int value;
    node* left;
    node* right;
    node(int value):value(value),left(NULL),right(NULL){}
    ~node(){}
};

node* _build_tree(int pre[],int start_pre,int mid[],int start_mid, int len){
    int value = pre[start_pre];
    node* root = new node(value);    
    int index=0;
    for(int i=start_mid;i<start_mid+len;i++){
        if(value==mid[i]){
            index = i;
            break;
        }
    }
    int left_len = index-start_mid;//左子树的长度
    if(left_len>0)root->left = _build_tree(pre,start_pre+1,mid,start_mid,left_len);
    int right_len = start_mid+len-index-1;//右子树的长度
    if(right_len>0)root->right = _build_tree(pre,start_pre+left_len+1,mid,index+1,right_len);
    return root;
}
//Create bitree according to the pre_order, and mid_order;
node* build_tree(int pre[],int mid[],int len){
    node* head=NULL;
    head=_build_tree(pre,0,mid,0,len);
    return head;
}

//Non-recursive pre-order
void pre_order_non(node* root){
    stack<node*> st;
    node* cur = root;
    while(cur!=NULL||!st.empty()){
        while(cur!=NULL){
            cout<<cur->value<<endl;
            st.push(cur);
            cur=cur->left;
        }
        cur = st.top();
        st.pop();
        cur = cur->right;
    }
}
//Non-recursive mid-order
void mid_order_non(node* root){
    //node* pnode = root;
    stack<node*> st;
    node* cur = root;
    while(cur!=NULL||!st.empty()){
        while(cur!=NULL){
            st.push(cur);
            cur = cur->left;
        }
        cur = st.top();
        cout<<cur->value<<endl;
        st.pop();
        cur = cur->right;
    }
}
//Non-recursive post-order
void post_order_non(node* root){
    stack<node*> st;
    node* cur = root;
    node* previsited = NULL;
    while(cur!=NULL||!st.empty()){
        while(cur!=NULL){
            st.push(cur);
            cur = cur->left;
        }
        cur = st.top();
        if(cur->right==NULL||cur->right==previsited){
            cout<<cur->value<<endl;
            st.pop();
            previsited = cur;
            cur = NULL;
        }else
            cur=cur->right;
    }
}
int main(){
    int length = 10;
    int pre[]={8,11,9,3,13,6,15,12,5,7};
    int mid[]={3,9,13,11,6,15,8,5,12,7};
    node* root = build_tree(pre,mid,length);
    mid_order_non(root);
    post_order_non(root);
    pre_order_non(root);
    system("pause");
}

 

posted @ 2015-08-26 11:25  舒克_贝塔  阅读(762)  评论(0编辑  收藏  举报