二叉树重建 二叉树的遍历(前、中、后序及层次遍历,递归和非递归实现)

一棵二叉树:

树的先序遍历序列preorder:DBACEGF(根左右)

树的中序遍历序列inorder:ABCDEFG(左根右)

树的后序遍历序列postorder:ACBFGED(左右根)

树的层序遍历序列levelorder:DBEACGF(按行遍历)

输入一棵二叉树的先序遍历和中序遍历序列,输出它的后序遍历序列。

  输入:DBACEGF ABCDEFG  输出:ACBFGED 

思路:

已知先序遍历序列的第一个一定是本树的根节点,而后在中序遍历中找到该根节点的位置,中序遍历序列中根节点左边为左子树,右边为右子树,然后开始先左子树后右子树进行递归,因为要求的后序遍历序列是左右根,故在递归完左右子树后再输出根。

 Code:

 1 #include<bits/stdc++.h>
 2 #define IO ios::sync_with_stdio(false)
 3 using namespace std;
 4 string preorder,inorder,aa;//分别为先序、中序、后序
 5 int n,t;
 6 void recover(int l,int r)
 7 {
 8     if(l>=r)return;
 9     int root=preorder[t++];//先序遍历的第一个点一定是根节点
10     int m=distance(inorder.begin(),find(inorder.begin(),inorder.end(),root));//找到中序中的根节点位置
11     recover(l,m);//根节点的左子树
12     recover(m+1,r);//右子树
13     aa.push_back(root);//因为要求后序遍历,所以根最后输出
14 }
15 int main()
16 {
17     IO;
18     while(!(cin>>preorder>>inorder).eof())
19     {
20         aa.clear();
21         t=0;
22         recover(0,preorder.size());
23         for(int i=0;i<aa.size();i++){
24             cout<<aa[i];
25         }
26         cout<<endl;
27     }
28     return 0;
29 }
View Code

输入一棵二叉树的中序遍历和后序遍历序列,输出它的先序遍历序列。   
 输入:
ABCDEFG ACBFGED 输出:DBACEGF

思路:
已知后序遍历的最后一个一定是本树的根节点,所以先从后序中找到当前树的根并输出(因为所要求的先序遍历是根左右,故找到根后就输出),然后去中序里

找该根的位置,将中序划为两棵子树(中序遍历中根节点左边为其左子树,右边为其右子树),之后开始进行递归。

Code:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 string preorder,inorder,postorder;
 4 void recover(int l,int r)
 5 {
 6     string t(inorder,l,r-l+1);//将中序序列inorder的l位置起r-l+1位复制给数组t
 7     int vis=postorder.find_last_of(t);//后序遍历所找到的最后一个一定当前序列t的根
 8     preorder.push_back(postorder[vis]);//要求先序,故先输出根,下面再分左右子树去递归
 9     int m=inorder.find(postorder[vis]);//根在中序遍历中的位置m,中序遍历中根左边为左子树,根右边为右子树
10     if(m!=l)
11         recover(l,m-1);//左子树递归
12     if(m!=r)
13         recover(m+1,r);//右子树递归
14 }
15 int main()
16 {
17     while(!(cin>>inorder>>postorder).eof())//输入中序遍历和后序遍历的序列
18     {
19         preorder.clear();//多测试用例故要清空
20         recover(0,inorder.size()-1);
21         cout<<preorder<<endl;//输出先序遍历序列
22     }
23     return 0;
24 }
View Code
 
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 void recover(string zhong,string hou){
 4     if(zhong.size()>0){
 5         char root=hou[hou.size()-1];//后序的最后一个为根节点
 6         cout<<root;//输出根
 7         int vis=zhong.find(root);//该根在中序中的位置
 8         recover(zhong.substr(0,vis),hou.substr(0,vis));//递归左子树
 9         recover(zhong.substr(vis+1),hou.substr(vis,zhong.size()-vis-1));//递归右子树
10     }
11 }
12 int main()
13 {
14     string inorder,postorder;
15     while(cin>>inorder>>postorder)
16     {
17         recover(inorder,postorder);
18         cout<<endl;
19     }
20     return 0;
21 }
View Code
知道中序和后序遍历,画二叉树和写出前序遍历

输入一颗二叉树的先序遍历和中序遍历序列,输出它的层序遍历序列。  
  输入:DBACEGF ABCDEFG 输出:DBEACGF
层序遍历思路:
创建一个队列,先将根节点入队,输出根节点,将根节点的儿子先左后右入队,根节点出队,如此循环直到队列为空。

Code:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 struct TreeNode
 4 {
 5     TreeNode *l,*r;
 6     char data;
 7 };
 8 TreeNode *create(char *pre,char *mid,int len) //三个参数分别为先序序列,中序序列,序列长度
 9 {
10     if(len<=0)
11         return NULL; //空节点
12     TreeNode *root;
13     root=new TreeNode;
14     root->data=pre[0]; //先序遍历的第一个一定是根节点,如此迭代
15     int i;
16     for(i=0;i<len;i++){
17         if(mid[i]==pre[0]) //在中序遍历中找到该根节点的位置
18             break;
19     }
20     root->l=create(pre+1,mid,i); //递归左子树,左子树中先序遍历字串向后挪一位,中序不变,但i控制了长度
21     root->r=create(pre+i+1,mid+i+1,len-i-1);//递归右子树,右子树中先序遍历和中序遍历都向后挪i+1位,长度变成总长度减去前半部分的长度
22     return root;
23 }
24 void levelorder(TreeNode *root) //层序遍历
25 {
26     queue<TreeNode*>que;//注意是TreeNode*
27     if(root){ //一定要特判,不然会RE
28         que.push(root);
29         cout<<que.front()->data;
30     }
31     while(que.size())
32     {
33         TreeNode *root=que.front();
34         que.pop();
35         if(root->l){ //依次找左右儿子输出
36             cout<<root->l->data;
37             que.push(root->l);
38         }
39         if(root->r){
40             cout<<root->r->data;
41             que.push(root->r);
42         }
43     }
44 }
45 void postorder(TreeNode *root) //后序遍历
46 {
47     if(!root)
48         return;
49     postorder(root->l);
50     postorder(root->r);
51     cout<<root->data;
52 }
53 
54 int main()
55 {
56     char preorder[1000],inorder[1000];
57     while(!(cin>>preorder>>inorder).eof())//输入先序遍历序列和中序遍历序列
58     {
59         TreeNode *root;
60         int len=strlen(preorder);
61         root=create(preorder,inorder,len);
62         levelorder(root);cout<<endl; //输出层序遍历序列
63         postorder(root);cout<<endl; //输出后序遍历序列
64     }
65     return 0;
66 }
View Code

猜你喜欢

转载自www.cnblogs.com/HOLLAY/p/11299198.html