二叉樹的幾個經典例題


 

二叉樹遍歷1

題目描述

編一個程序,讀入用戶輸入的一串先序遍歷字符串,根據此字符串建立一個二叉樹(以指針方式存儲)。 例如如下的先序遍歷字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空樹。建立起此二叉樹以后,再對二叉樹進行中序遍歷,輸出遍歷結果。

輸入描述:

輸入包括1行字符串,長度不超過100。

輸出描述:

可能有多組測試數據,對於每組數據,
輸出將輸入字符串建立二叉樹后中序遍歷的序列,每個字符后面都有一個空格。
每個輸出結果占一行。

輸入

abc##de#g##f###

輸出

c b e g d f a 
思路:遞歸建樹。每次都獲取輸入字符串的當前元素,根據題目要求(先序、中序、后序等+其他限制條件)建樹。再根據題目要求輸出即可。
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 struct node{
 4     char data;
 5     node *lchild,*rchild;
 6     node(char c):data(c),lchild(NULL),rchild(NULL){}
 7 };
 8 string s;
 9 int loc;
10 node* create(){
11     char c=s[loc++];//獲取每一個字符串元素
12     if(c=='#') return NULL;
13     node *t=new node(c);//創建新節點
14     t->lchild=create();
15     t->rchild=create();
16     return t;
17 }
18 void inorder(node *t){//遞歸中序
19     if(t){
20         inorder(t->lchild);
21         cout<<t->data<<' ';
22         inorder(t->rchild);
23     }
24 }
25 int main(){
26     while(cin>>s){
27         loc=0;
28         node *t=create();//先序遍歷建樹
29         inorder(t);//中序遍歷 並輸出
30         cout<<endl;
31     }
32     return 0;
33 }

 

 

二叉樹遍歷2

題目描述

二叉樹的前序、中序、后序遍歷的定義: 前序遍歷:對任一子樹,先訪問跟,然后遍歷其左子樹,最后遍歷其右子樹; 中序遍歷:對任一子樹,先遍歷其左子樹,然后訪問根,最后遍歷其右子樹; 后序遍歷:對任一子樹,先遍歷其左子樹,然后遍歷其右子樹,最后訪問根。 給定一棵二叉樹的前序遍歷和中序遍歷,求其后序遍歷(提示:給定前序遍歷與中序遍歷能夠唯一確定后序遍歷)。

輸入描述:

兩個字符串,其長度n均小於等於26。
第一行為前序遍歷,第二行為中序遍歷。
二叉樹中的結點名稱以大寫字母表示:A,B,C....最多26個結點。

輸出描述:

輸入樣例可能有多組,對於每組測試樣例,
輸出一行,為后序遍歷的字符串。
示例1

輸入

ABC
BAC
FDXEAG
XDEFAG

輸出

BCA
XEDGAF
思路:由題目信息,先序+中序可遞歸建立二叉樹(還是每次根據條件選取當前一個元素 加入樹,在遞歸遍歷即可),再按照題目要求輸出即可。
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 struct node{
 4     char data;
 5     node *lchild,*rchild;
 6     node(char c):data(c),lchild(NULL),rchild(NULL){}
 7 };
 8 node *create(string a,string b){//前序+中序--遞歸建樹
 9     if(a.size()==0) return NULL;//空字符串--遞歸出口
10     char c=a[0];//根節點
11     node *t=new node(c);//創建新節點
12     int pos=b.find(c);//找到根節點在b中的位置
13     t->lchild=create(a.substr(1,pos),b.substr(0,pos));
14     t->rchild=create(a.substr(pos+1),b.substr(pos+1));
15     return t;
16 }
17 void postorder(node *t){
18     if(t){//后序遍歷
19         postorder(t->lchild);
20         postorder(t->rchild);
21         cout<<t->data;
22     }
23 }
24 int main(){
25     string a,b;
26     while(cin>>a>>b){
27         node *t=create(a,b);
28         postorder(t);
29         cout<<endl;
30     }
31     return 0;
32 }

 

 二叉排序樹1

題目描述

二叉排序樹,也稱為二叉查找樹。可以是一顆空樹,也可以是一顆具有如下特性的非空二叉樹: 1. 若左子樹非空,則左子樹上所有節點關鍵字值均不大於根節點的關鍵字值; 2. 若右子樹非空,則右子樹上所有節點關鍵字值均不小於根節點的關鍵字值; 3. 左、右子樹本身也是一顆二叉排序樹。 現在給你N個關鍵字值各不相同的節點,要求你按順序插入一個初始為空樹的二叉排序樹中,每次插入后成功后,求相應的父親節點的關鍵字值,如果沒有父親節點,則輸出-1。

輸入描述:

輸入包含多組測試數據,每組測試數據兩行。
第一行,一個數字N(N<=100),表示待插入的節點數。
第二行,N個互不相同的正整數,表示要順序插入節點的關鍵字值,這些值不超過10^8。

輸出描述:

輸出共N行,每次插入節點后,該節點對應的父親節點的關鍵字值。
示例1

輸入

5
2 5 1 3 4

輸出

-1
2
2
5
3
思路:二叉排序樹基本思路是 按照中序遍歷得到遞增序列 的特點來建樹。
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 struct node{
 4     int data;
 5     node *lchild,*rchild;
 6     node(int x):data(x),lchild(NULL),rchild(NULL){}
 7 };
 8 node *create(node *t,int x){
 9     if(t==NULL)
10         t=new node(x);//創建新節點
11     else if(x<t->data){
12         if(t->lchild==NULL) cout<<t->data<<endl;//如果左子樹為空,則直接插入值,並且當前節點就是父節點,輸出。否則繼續遞歸建樹
13         t->lchild=create(t->lchild,x);
14     }else if(x>t->data){
15         if(t->rchild==NULL) cout<<t->data<<endl;
16         t->rchild=create(t->rchild,x);
17     }
18     return t;
19 }
20 int main(){
21     int n;
22     while(cin>>n){
23         node *t=NULL;
24         for(int i=0;i<n;i++){
25             int x;
26             cin>>x;
27             if(t==NULL) cout<<-1<<endl;
28             t=create(t,x);
29         }
30     }
31     return 0;
32 }

 

 二叉排序樹2

題目描述

輸入一系列整數,建立二叉排序樹,並進行前序,中序,后序遍歷。

輸入描述:

輸入第一行包括一個整數n(1<=n<=100)。
接下來的一行包括n個整數。

輸出描述:

可能有多組測試數據,對於每組數據,將題目所給數據建立一個二叉排序樹,並對二叉排序樹進行前序、中序和后序遍歷。
每種遍歷結果輸出一行。每行最后一個數據之后有一個空格。

輸入中可能有重復元素,但是輸出的二叉樹遍歷序列中重復元素不用輸出。
示例1

輸入

5
1 6 5 9 8

輸出

1 6 5 9 8 
1 5 6 8 9 
5 8 9 6 1
思路:二叉排序樹基本思路是 按照中序遍歷得到遞增序列 的特點來建樹。
 
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 struct node{
 4     int data;
 5     node *lchild,*rchild;
 6     node(int x):data(x),lchild(NULL),rchild(NULL){}
 7 };
 8 node *insert(node *t,int x){//中序建立二叉排序樹~
 9     if(t==NULL) t=new node(x);
10     else if(x<t->data) t->lchild=insert(t->lchild,x);
11     else if(x>t->data) t->rchild=insert(t->rchild,x);
12     return t;
13 }
14 void preorder(node *t){
15     if(t){
16         cout<<t->data<<' ';
17         preorder(t->lchild);
18         preorder(t->rchild);
19     }
20 }
21 void inorder(node *t){
22     if(t){
23         inorder(t->lchild);
24         cout<<t->data<<' ';
25         inorder(t->rchild);
26     }
27 }
28 void postorder(node *t){
29     if(t){
30         postorder(t->lchild);
31         postorder(t->rchild);
32         cout<<t->data<<' ';
33     }
34 }
35 int main(){
36     int n;
37     while(cin>>n){
38         node *t=NULL;
39         for(int i=0;i<n;i++){
40             int x;
41             cin>>x;
42             t=insert(t,x);
43         }
44         preorder(t); cout<<endl;
45         inorder(t); cout<<endl;
46         postorder(t); cout<<endl;
47     }
48     return 0;
49 }

 

 

 

 二叉排序樹3*****

 

題目描述

 

判斷兩序列是否為同一二叉搜索樹序列

輸入描述:

開始一個數n,(1<=n<=20) 表示有n個需要判斷,n= 0 的時候輸入結束。
接下去一行是一個序列,序列長度小於10,包含(0~9)的數字,沒有重復數字,根據這個序列可以構造出一顆二叉搜索樹。
接下去的n行有n個序列,每個序列格式跟第一個序列一樣,請判斷這兩個序列是否能組成同一顆二叉搜索樹。

輸出描述:

如果序列相同則輸出YES,否則輸出NO
示例1

輸入

2
567432
543267
576342
0

輸出

YES
NO
思路:先按照中序遍歷得到遞增序列的特點建立二叉樹,然后再按照先序遍歷輸出,如果兩個序列建立的二叉樹先序遍歷結果相同,那么說明為同一二叉搜索樹(因為先序遍歷+中序遍歷可以唯一確定一棵二叉樹)
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int loc;
 4 struct node{
 5     char data;
 6     node *lchild,*rchild;
 7     node(char c):data(c),lchild(NULL),rchild(NULL){}
 8 };
 9 node* insert(node *t,char x){
10     if(t==NULL)
11         t=new node(x);
12     else if(x<t->data){
13         t->lchild=insert(t->lchild,x);
14     }
15     else if(x>t->data){
16         t->rchild=insert(t->rchild,x);
17     }
18     return t;
19 }
20 void preorder(node *t,char pre[]){
21     if(t){
22         pre[loc++]=t->data;
23         pre[loc]=0;
24         preorder(t->lchild,pre);
25         preorder(t->rchild,pre);
26     }
27 }
28 int main(){
29     int n;
30     while(cin>>n){
31         if(n==0)
32             break;
33         node *t1=NULL,*t2;
34         string s1,s2;
35         loc=0;
36         cin>>s1;
37         for(int i=0;i<s1.size();i++){
38             t1=insert(t1,s1[i]);
39         }
40         for(int i=0;i<n;i++){
41             t2=NULL;
42             cin>>s2;
43             for(int i=0;i<s1.size();i++){
44                 t2=insert(t2,s2[i]);
45             }
46             char a[24],b[24];
47             preorder(t1,a);
48             loc=0;
49             preorder(t2,b);
50             loc=0;
51             string s=strcmp(a,b)==0?"YES":"NO";
52             cout<<s<<endl;
53         }
54     }
55     return 0;
56 }

 

二叉樹性質1

題目描述

    如上所示,由正整數1,2,3……組成了一顆特殊二叉樹。我們已知這個二叉樹的最后一個結點是n。現在的問題是,結點m所在的子樹中一共包括多少個結點。     比如,n = 12,m = 3那么上圖中的結點13,14,15以及后面的結點都是不存在的,結點m所在子樹中包括的結點有3,6,7,12,因此結點m的所在子樹中共有4個結點。

輸入描述:

    輸入數據包括多行,每行給出一組測試數據,包括兩個整數m,n (1 <= m <= n <= 1000000000)。

輸出描述:

    對於每一組測試數據,輸出一行,該行包含一個整數,給出結點m所在子樹中包括的結點的數目。
示例1

輸入

3 12
0 0

輸出

4
思路二叉樹父子節點的關系。
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int slv(int m,int n){
 4     if(m>n) return 0;
 5     else return 1+slv(2*m,n)+slv(2*m+1,n);//遞歸。-實際上是完全二叉樹
 6 }
 7 int main(){
 8     int m,n;
 9     while(cin>>m>>n){
10         cout<<slv(m,n)<<endl;
11     }
12     return 0;
13 }

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM