zoukankan      html  css  js  c++  java
  • 二叉树的建立,以及非递归遍历

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

    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");
    }
  • 相关阅读:
    数据结构之单链表的实现java
    从尾到头打印列表——牛客剑指offer
    Java重要类之LinkedList
    删除链表中重复的结点——牛客剑指offer
    二维数组中的查找——牛客剑指offer
    爬虫常见异常
    持续集成常见异常及排除方案
    VMware安装与基本使用
    web开发常见异常及处理
    Linux简单介绍与基本使用(微系统,)
  • 原文地址:https://www.cnblogs.com/zhang-wen/p/4759842.html
Copyright © 2011-2022 走看看