[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 }
原文地址:https://www.cnblogs.com/TaigaCon/p/2843315.html