zoukankan      html  css  js  c++  java
  • 日常编程练习(三)

    一、树的遍历算法

    树的创建

    struct BinaryTreeNode
    {
        int val;
        BinaryTreeNode* left;
        BinaryTreeNode* right;
    };
    
    void creat_tree(BinaryTreeNode* &T)
    {
        char a;
        cin>>a;
        if(a=='#')
            T=NULL;
        else
        {
            T=new BinaryTreeNode;
            if(T==NULL)
                return;
            T->val=a-'0';
            creat_tree(T->left);
            creat_tree(T->right);
        }
    }

    前序遍历

    void pre_trave1(BinaryTreeNode* T)
    {
        if(T==NULL)
            return;
        else
        {
            cout<<T->val<<" ";
            pre_trave1(T->left);
            pre_trave1(T->right);
        }
    }
    
    //非递归实现
    void pre_trave2(BinaryTreeNode* T)
    {
        if(T==NULL)
            return;
        stack<BinaryTreeNode*> st_T;
        while(1)
        {
            cout<<T->val;
            while(T)
            {
                if(T->right)
                    st_T.push(T->right);   //先遍历左子树,遇到右子树入栈
                if(T->left)
                    cout<<T->left->val;
                T=T->left;
            }
            if(!st_T.empty())
            {
                T=st_T.top();
                st_T.pop();
            }
            else
                break;
        }
    }

    中序遍历

    void mid_trave1(BinaryTreeNode* T)
    {
        if(T==NULL)
            return;
        else
        {
            mid_trave1(T->left);
            cout<<T->val<<" ";
            mid_trave1(T->right);
        }
    }
    
    //非递归实现
    void mid_trave2(BinaryTreeNode* T)
    {
        if(T==NULL)
            return;
        stack<BinaryTreeNode*> st_T;
        while(1)
        {
            while(T)
            {
                st_T.push(T);     //逢左子树入栈
                T=T->left;
            }
            if(!st_T.empty())
            {
                T=st_T.top();
                st_T.pop();
                cout<<T->val<<" ";
                T=T->right;
            }
            else
                break;
        }
    }

    后序遍历

    //递归实现
    void post_trave1(BinaryTreeNode* T)
    {
        if(T==NULL)
            return;
        else
        {
            post_trave1(T->left);
            post_trave1(T->right);
            cout<<T->val<<" ";
        }
    }
    //非递归实现(破坏树的原结构)
    void post_trave2(BinaryTreeNode* T)
    {
        if(T==NULL)
            return;
        stack<BinaryTreeNode*> st_T;
        while(1)
        {
            while(T)
            {
                st_T.push(T);
                T=T->left;
            }
            if(!st_T.empty())
            {
                T=st_T.top();
                if(T->right)      //第一次经过根节点后打断与右子树的联系
                {
                    BinaryTreeNode* temp=T->right;     
                    T->right=NULL;
                    T=temp;
                }
                else
                {
                    st_T.pop();
                    cout<<T->val<<" ";
                    T=NULL;
                }
    
            }
            else break;
        }
    }
    //非递归实现
    void post_trave3(BinaryTreeNode* T)
    {
        if(T==NULL)
            return;
        stack<BinaryTreeNode*> st_T;
        BinaryTreeNode* pre;
        while(1)
        {
            while(T)
            {
                st_T.push(T);
                T=T->left;
            }
            if(!st_T.empty())
            {
                T=st_T.top();
                if(T->right&&(pre!=T->right))  //当存在右子树且右子树没被打印时,先打印右子树
                {
                   T=T->right;
                }
                else
                {
                    pre=T;
                    st_T.pop();
                    cout<<T->val<<" ";
                    T=NULL;
                }
            }
            else break;
        }
    }

    层序遍历

    void level_trave(BinaryTreeNode* T)
    {
        if(!T)
            return;
        queue<BinaryTreeNode*> qu_T;
        qu_T.push(T);
        while(!qu_T.empty())
        {
            BinaryTreeNode* temp=qu_T.front();
            qu_T.pop();
            if(temp->left!=NULL)
                qu_T.push(temp->left);
            if(temp->right!=NULL)
                qu_T.push(temp->right);
            cout<<temp->val<<" ";
        }
    }

     二、重建二叉树

    问题描述:输入二叉树的前序与中序,输出重建的二叉树。

    //很明显前序的首位是根结点,再从中序中查找根结点,就可以分为左右两个子树,依次递归可得。
    //递归条件和边界一定要分析清楚,不然很容易出错
    BinaryTreeNode* core_rebuild(vector<int>&,int,int,vector<int>&,int,int); BinaryTreeNode* rebulid_bT(vector<int>& pre,vector<int>& mid,int length) { if(!pre.size()||!mid.size()||length<=0) { return NULL; } return core_rebuild(pre,0,length-1,mid,0,length-1); } BinaryTreeNode* core_rebuild(vector<int>& pre,int pre_start,int pre_end,vector<int>& mid,int mid_start,int mid_end) { BinaryTreeNode* root=new BinaryTreeNode; root->val=pre[pre_start]; root->left=NULL; root->right=NULL; if(pre_start==pre_end) { return root; } int temp=mid_start; while(temp<=mid_end&&pre[pre_start]!=mid[temp]) temp++; int count=temp - mid_start; if(count>0) //temp不处于开始位置,则有左子树 root->left=core_rebuild(pre,pre_start+1,pre_start+count,mid,mid_start,temp-1); if(temp!=mid_end) //temp不处于终止位置,则有右子树 root->right=core_rebuild(pre,pre_start+count+1,pre_end,mid,temp+1,mid_end); return root; }

    问题描述:输入二叉树的后序与中序,输出重建的二叉树。

    BinaryTreeNode* core_rebuild2(vector<int>&,int,int,vector<int>&,int,int);
    BinaryTreeNode* rebulid_bT(vector<int>& pre,vector<int>& mid,int length)
    {
        if(!pre.size()||!mid.size()||length<=0)
        {
            return NULL;
        }
        return core_rebuild2(pre,0,length-1,mid,0,length-1);
    }
    
    BinaryTreeNode* core_rebuild2(vector<int>& post,int post_start,int post_end,vector<int>& mid,int mid_start,int mid_end)
    {
        BinaryTreeNode* root=new BinaryTreeNode;
        root->val=post[post_end];
        root->left=NULL;
        root->right=NULL;
        if(post_start==post_end)
        {
            return root;
        }
        int temp=mid_start;
        while(post[post_end]!=mid[temp])
            temp++;
        int count=temp-mid_start;
        if(count>0)
            root->left=core_rebuild2(post,post_start,post_start+count-1,mid,mid_start,temp-1);
        if(temp<mid_end)
            root->right=core_rebuild2(post,post_start+count,post_end-1,mid,temp+1,mid_end);
        return root;
    }
  • 相关阅读:
    第一章:简介
    2018年10月底新公司
    第四章:集成
    第三章:如何建模服务
    第二章:演化架构师
    第一章:微服务
    4、工厂模式
    5、单例模式
    8、模板方法模式
    3、字典介绍
  • 原文地址:https://www.cnblogs.com/kiplove/p/6810353.html
Copyright © 2011-2022 走看看