---恢復內容開始---c++
在計算機科學中,二叉樹是每一個結點最多有兩個子樹的有序樹。一般子樹的根被稱做「左子樹」(left subtree)和「右子樹」(right subtree)。二叉樹常被用做二叉查找樹和二叉堆或是二叉排序樹。spa
也就五種,從左往右分別是空樹,只有根節點的樹,根節點和左兒子,根節點和右孩子,根節點和左右孩子。3d
1.二叉樹第i層上的結點數目最多爲2i-1(i>=1)code
2.深度爲k的二叉樹至多有2k-1個結點(k>=1)blog
3.包含n個結點的二叉樹的高度至少爲(log2n)+1排序
4.在任意二叉樹中,若度爲0的個數爲n0,度爲2的結點數爲n2,則n0=n2+1遞歸
5.若是對一棵有n個節點的徹底二叉樹的節點按層序編號(從第一層開始到最下一層,每一層從左到右編號),對任一節點i有:ci
就像它的名字同樣,它是滿的(廢話)get
滿二叉樹是指一個高度爲n的樹有2^(n-1)個結點(其實就是每一個點都有兩個孩子,除了最後一層的單身狗)string
徹底二叉樹是指一顆二叉樹的葉子結點只在最後兩層,而且最後一層的葉子結點都集中在左邊。顯然,滿二叉樹也是一顆徹底二叉樹。
對於二叉樹的遍歷,咱們分爲三種狀況:
如下順序就是124583796
1 void work(int x) 2 { 3 if(!x)return;//若是這個點有效 4 printf("%d ",x);//根 5 work(l[x]);//左子樹 6 work(r[x]);//右子樹 7 }
如下順序就是428519736
1 void work(int x) 2 { 3 if(!x)return;//若是這個點有效 4 work(l[x]);//左子樹 5 printf("%d ",x);//根 6 work(r[x]);//右子樹 7 }
如下順序就是485297631
void work(int x) { if(!x)return;//若是這個點有效 work(r[x]);//右子樹 work(l[x]);//左子樹 printf("%d ",x);//根 }
然而它們之間有神奇的關係
圖中粉色的表示這一個序分紅了根,左,右三部分(也可能沒有左或右)
首先,你要知道,後序的最後一個確定是根結點,而後你要知道,在一串中序中,找到了它的根結點,那麼它左邊就是左子樹,右邊就是右子樹。
咱們先找到根結點A,而後把中序分爲FDBE和CHG左右子樹,而左子樹的後序就是FDEB,右子樹的後序就是HGC,而後一步一步分解下去,知道不能分解,由於咱們求先序,因此先輸出根結點,而後分別遞歸左、右子樹。
1 #include<bits/stdc++.h> 2 using namespace std; 3 void beford(string s2,string s3)//中序and後序 4 { 5 if(s2.size()==0)return; 6 char root=s3[s3.size()-1];//找到根結點 7 cout<<root; //輸出根結點 8 int k=s2.find(root); 9 beford(s2.substr(0,k),s3.substr(0,k));//左子樹 10 beford(s2.substr(k+1),s3.substr(k,s2.size()-k-1));//右子樹 11 } 12 int main() 13 { 14 string s2,s3;//1,2,3分別對應前,中,後 15 cin>>s2>>s3; 16 beford(s2,s3); 17 }
與上面同理,只須要稍微改動一點便可
1 #include<bits/stdc++.h> 2 using namespace std; 3 void beford(string s1,string s2)//先序and中序 4 { 5 if(s1.size()==0)return; 6 char root=s1[0];//找到根結點 7 int k=s2.find(root); 8 beford(s1.substr(1,k),s2.substr(0,k));//左子樹 9 beford(s1.substr(k+1),s2.substr(k+1));//右子樹 10 cout<<root; //輸出根結點 11 } 12 int main() 13 { 14 string s1,s2;//1,2,3分別對應前,中,後 15 cin>>s1>>s2; 16 beford(s1,s2); 17 }