zoukankan      html  css  js  c++  java
  • [c++]已知二叉树的前序遍历与中序遍历结果(二叉树中不含重复数字),重构二叉树

    比如说某二叉树

    前序遍历结果:

    1 2 4 7 3 5 6 8

    中序遍历结果:

    4 7 2 1 5 3 8 6

    前序遍历就是先输出根节点,然后左节点,然后右节点

    中序遍历就是先输出左节点,然后根节点,最后右节点

    对于上面的二叉树我们可以这样分析:

    1 2 4 7 3 5 6 8

                                                                               

    4 7 2 1 5 3 8 6

    其中绿色的为根结点,也就是1

    然后通过中序遍历结果,得到 1 左边的(粉红)为左子树,右边的(浅蓝)为右子树,

    左子树跟右子树在前序遍历的结果中,我们能根据左子树跟右子树的大小划分开来,

    然后就得到了一颗根节点为 ,另一颗跟节点为 的二叉树了,

    如此递归下去就能得到一颗完整的二叉树。

    以下为c++实现的代码:

    基于gcc version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)

      1 /*已知二叉树的前序、中序遍历,重建二叉树*/
      2 
      3 #include <iostream>
      4 #include <list>
      5 #include <sstream>
      6 using namespace std;
      7 struct tree{
      8     int m_nValue;
      9     tree *l_tree;
     10     tree *r_tree;
     11 }*root;
     12 
     13 /*重建二叉树的主函数,通过递归重建
     14  *f_begin:前序遍历头结点
     15  *f_end :  前序遍历末尾节点
     16  *m_begin:中序遍历头结点
     17  *m_end:  中序遍历末尾节点
     18  */
     19 tree *rebuild_tree(list<int>::iterator f_begin,list<int>::iterator f_end,list<int>::iterator m_begin,list<int>::iterator m_end);
     20     
     21 /*显示重建后的二叉树*/    
     22 void show_tree(tree *root);
     23 
     24 /*实现对list迭代器的整型加法,itr为迭代器,i为所加的整数*/
     25 list<int>::iterator pluss(list<int>::iterator itr,int i);
     26     
     27 /*计算出迭代器find_相对于begin的距离,范围是begin到end,并且把所找到的迭代器赋给res*/    
     28 int dist(list<int>::iterator begin,list<int>::iterator end,list<int>::iterator find_,list<int>::iterator &res);
     29 
     30 /*convert是把string转换到list<int>容器内的转换函数*/
     31 void convert(string &str,list<int> &i_list);
     32 
     33 void free_tree(void);
     34 
     35 /*前序l_front,中序l_mid*/
     36     static list<int> l_front;
     37     static list<int> l_mid;
     38     
     39     /*list_head用于记录所创建的tree 
     40      *index用于记录tree指针所存的位置
     41      */
     42     static tree *list_head[100];
     43     static int tree_index;
     44 
     45 int main()
     46 {
     47     string front;
     48     string mid;
     49     
     50     tree_index=0;
     51 
     52 
     53     cout<<"请输入树的前序遍历序列(空格隔开):"<<endl;
     54     getline(cin,front);
     55 
     56     cout<<"请输入树的中序遍历序列(空格隔开):"<<endl;
     57     getline(cin,mid);
     58 
     59     
     60     convert(front,l_front);
     61     convert(mid,l_mid);
     62     
     63     /*这里不考虑.end()因为后面迭代的时候分段,list段内是没有.end()的,而,rebuild_tree是需要递归的函数,这样是为了保持一致性*/
     64     root=rebuild_tree(l_front.begin(),--l_front.end(),l_mid.begin(),--l_mid.end());
     65     
     66     cout<<"Show Tree"<<endl;
     67     show_tree(root);
     68     cout<<endl;
     69     free_tree();
     70 }
     71 
     72 tree *rebuild_tree(list<int>::iterator f_begin,list<int>::iterator f_end,list<int>::iterator m_begin,list<int>::iterator m_end)
     73 {
     74     list<int>::iterator tmp,res;
     75         list<int>::iterator tmp1,tmp2,tmp3;
     76         int dis;
     77         tree *root=(tree*)malloc(sizeof(tree));
     78         
     79         list_head[tree_index]=root;
     80         tree_index++;
     81         
     82         dis=dist(m_begin,m_end,f_begin,res);
     83         root->m_nValue=*f_begin;        
     84 
     85         cout<<"dis:"<<dis<<endl;        
     86         
     87         /*如果list内的数据已经被加入二叉树节点,那么把该list的节点赋值为-1,便于后面判断边界*/
     88         *f_begin=-1;
     89             
     90                 
     91 /*---------------------如果有左子树,往左遍历-----------------------------*/        
     92         tmp=res;
     93 /*---------------------如果dis为0,则说明没左子树-------------------------------*/    
     94         if(tmp==l_mid.begin()||dis==0)
     95             {
     96                 root->l_tree=NULL;
     97             }
     98             else if(*(--tmp)==-1)
     99                     {
    100                         root->l_tree=NULL;
    101                     }
    102         else
    103             {
    104         tmp1=pluss(f_begin,1);
    105         tmp2=pluss(f_begin,dis);
    106         tmp3=pluss(m_begin,dis-1);
    107         
    108         root->l_tree=rebuild_tree(tmp1,tmp2,m_begin,tmp3);
    109             }
    110 /*-----------------------如果有右子树,往右遍历---------------------------*/    
    111     
    112         tmp=res;
    113         /*如果搜索所得的结果为该中序遍历list段尾部,那么他的右子树为NULL*/
    114     if(tmp==m_end)
    115         {    
    116             root->r_tree=NULL;
    117         }
    118         else{
    119             tmp++;
    120      if(*tmp==-1|| tmp==l_mid.end())
    121         {
    122             root->r_tree=NULL;
    123         }
    124     else
    125         {
    126             tmp1=pluss(f_begin,dis+1);
    127             tmp2=pluss(res,1);
    128             
    129             root->r_tree=rebuild_tree(tmp1,f_end,tmp2,m_end);
    130         }
    131 }
    132 /*------------------------------------------------------------------*/    
    133     cout<<"add node:"<<root->m_nValue<<endl;
    134         return root;
    135 }
    136 
    137 list<int>::iterator pluss(list<int>::iterator itr,int i)
    138     {
    139         for(;i>0;i--)
    140         {
    141         itr++;
    142     }
    143         return itr;
    144     }
    145 
    146 int dist(list<int>::iterator begin,list<int>::iterator end,list<int>::iterator find_,list<int>::iterator &res)
    147 {
    148     res=find_;
    149     int i=0;
    150     end++;
    151 do
    152 {
    153     if(*begin==*res)
    154         {
    155             res=begin;
    156             return i;
    157         }
    158         i++;
    159         begin++;
    160 }while(begin!=end);
    161 
    162     if(res!=l_mid.end())
    163     *res=-1;
    164 
    165         return -1;
    166 }
    167 
    168 void show_tree(tree *root)
    169 {
    170     cout<<root->m_nValue<<",";
    171     if(root->l_tree)
    172         {
    173             show_tree(root->l_tree);
    174         }
    175     if(root->r_tree)
    176     {
    177         show_tree(root->r_tree);
    178     }
    179 }
    180 
    181 void convert(string &str,list<int> &i_list)
    182 {
    183     int i;
    184 
    185     stringstream strOutput(str);
    186     for(;strOutput>>i;)
    187     {        
    188         i_list.push_back(i);
    189     }
    190     
    191 }
    192 
    193 void free_tree(void)
    194 {
    195     for(;tree_index>=0;tree_index--)
    196     free(list_head[tree_index]);
    197 }
  • 相关阅读:
    关于document.referrer的使用需要注意
    Vue2.0表单校验组件vee-validate的使用
    Ubuntu 20.04 Docker 安装并配置
    换硬盘,装win10系统小记
    关于MongoDB ObjectId的那些事儿
    水平垂直居中常见解决方案
    JSON基础知识总结
    css选择器中:first-child与:first-of-type的区别
    基于jQuery选择器的整理集合
    DOM对象与jquery对象有什么不同
  • 原文地址:https://www.cnblogs.com/TaigaCon/p/2843315.html
Copyright © 2011-2022 走看看