日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Tree Recovery(二叉树递归遍历+求后序遍历模板)

發布時間:2023/12/4 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Tree Recovery(二叉树递归遍历+求后序遍历模板) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題意:已知先序和中序,將后序求出來

Little Valentine liked playing with binary trees very much. Her favorite game was constructing randomly looking binary trees with capital letters in the nodes.?
This is an example of one of her creations:?

D/ \/ \B E/ \ \/ \ \A C G//F


To record her trees for future generations, she wrote down two strings for each tree: a preorder traversal (root, left subtree, right subtree) and an inorder traversal (left subtree, root, right subtree). For the tree drawn above the preorder traversal is DBACEGF and the inorder traversal is ABCDEFG.?
She thought that such a pair of strings would give enough information to reconstruct the tree later (but she never tried it).?

Now, years later, looking again at the strings, she realized that reconstructing the trees was indeed possible, but only because she never had used the same letter twice in the same tree.?
However, doing the reconstruction by hand, soon turned out to be tedious.?
So now she asks you to write a program that does the job for her!?

Input

The input will contain one or more test cases.?
Each test case consists of one line containing two strings preord and inord, representing the preorder traversal and inorder traversal of a binary tree. Both strings consist of unique capital letters. (Thus they are not longer than 26 characters.)?
Input is terminated by end of file.?
?

Output

For each test case, recover Valentine's binary tree and print one line containing the tree's postorder traversal (left subtree, right subtree, root).

Sample Input

DBACEGF ABCDEFG BCAD CBAD

Sample Output

ACBFGED CDAB

提供三種解法:

前序遍歷:根左右
中序遍歷:左根右
后序遍歷:左右根

例如上圖:
前序遍歷:ABEHFCGI
中序遍歷:HEBFACIG

1 思路
前序遍歷第一個字母A,必定是這樹的根節點
中序遍歷中找到A的位置把中序遍歷分成兩個子樹:HEBF和CIG,
取前序遍歷中的第二個點B,在分成的兩個子樹中找到B的位置,再次分成兩個子樹。HE和F,以此類推,分到不能再分了。
回溯到A點,對右子樹CIG進行同樣的操作。

#include<cstdio> #include<cstring> char be[100],en[100]; int n; void build(int t1,int t2) {if(t1>t2)return;n++;int u=strchr(en,be[n])-en;build(t1,u-1);build(u+1,t2);/*分為左子樹和右子樹區間分別查找*/printf("%c",en[u]); } int main() {while(~scanf("%s%s",be,en)){n=-1;build(0,strlen(be)-1);printf("\n");}return 0; }

2

思路
前序遍歷第一個字母A,必定是這樹的根節點
中序遍歷中找到A的位置把中序遍歷分成兩個子樹:HEBF和CIG,

根據A的位置,在前序中找到分界點(分界點+1=右節點)j=l1+(i-l2); 確定左子樹和右子樹在先序遍歷的分界點j,即右子樹的父節點
后序遍歷:左右根,故用棧存入根右左節點

#include<stdio.h> #include<string.h> #include<algorithm> #include<stack> using namespace std; char w[10010],s[10010]; int n,pre[10010],in[10010]; //先序數組和后序數組 stack<int> st; //存放父節點void build(int l1,int r1,int l2,int r2) //l1,r1,是先序遍歷的數組的開始和末尾,l2,r2是中序遍歷的數組的開始和末尾 {int i,j;st.push(pre[l1]); //父節點入棧for(i=l2; i<=r2; i++)if(in[i]==pre[l1]) //找到父節點在中序遍歷的位置ibreak;j=l1+(i-l2+1); //確定左子樹和右子樹在先序遍歷的分界點j,即右子樹的父節點if(j<=r1 && i+1<=r2) //求解右子樹build(j,r1,i+1,r2);if(l1+1<=j-1 && l2<=i-1) //求解左子樹build(l1+1,j-1,l2,i-1); }int main() {while(~scanf("%s",w)){int n=strlen(w);for(int i=0; i<n; i++)pre[i]=w[i]-'A';scanf("%s",s);for(int i=0; i<n; i++)in[i]=s[i]-'A';build(0,n-1,0,n-1);while(!st.empty()){printf("%c",st.top()+'A');st.pop();}printf("\n");}return 0; }

3

利用遞歸,從前序一個個元素開始,m=1; 在中序中找到in[i] == pre[m],
?然后將中序分為兩部分,in[1.....i-1] ?和in[i+1.....n],然后分別遍歷這兩
?部分,直到這兩部分元素為0(s>t) 或1個(s==t);

1.左子樹 ,左子樹范圍必定在begin到i-1之間,下一個根的位置在root+1

2.右子樹,右子樹范圍必定在i+1到end之間,根的位置就是(i-begin)是左子樹

的大小,相當于root位置往后移左子樹的個數再加一

#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int M=1e3+10; int a[M],b[M]; int n; void dfs(int x,int y,int root) {int i;if(x>y) return ;for(i=x;i<=y;i++)if(a[root]==b[i])break;dfs(x,i-1,root+1);dfs(i+1,y,root+(i-x)/**左子樹大小*/+1);/**右子樹,右子樹范圍必定在i+1到end之間,根的位置就是(i-begin)是左子樹的大小,相當于root位置往后移左子樹的個數再加一*/printf("%d%c",a[root],root==1?'\n':' '); } int main() {while(~scanf("%d",&n)){for(int i=1;i<=n;i++)scanf("%d",&a[i]);for(int i=1;i<=n;i++)scanf("%d",&b[i]);dfs(1,n,1);}return 0; }

?

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的Tree Recovery(二叉树递归遍历+求后序遍历模板)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。