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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

二叉树操作整理

發布時間:2024/1/17 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二叉树操作整理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

普通的二叉樹也涉及很多基本操作:構建,各種遍歷(前中后及分層),求節點數(總節點數、葉節點數、某一層節點數),構建鏡像,判斷是否同構,是否是BST、AVL、CBT,計算兩點間距離,求兩點最低公共祖先節點,由前中綴數列、中后綴數列重建等等(重建一棵二叉樹必須要有中綴數列,否則無法劃分左右子樹)。下面是我對這些基本操作的實現代碼,盡可能的包括了遞歸和非遞歸兩種方式(未完待續)。

首先,樹的節點定義如下

typedef struct node Bit_Node; struct node{TYPE key;struct node *l_child, *r_child; };

構建二叉樹

這個比較簡單,直接放代碼了。

Bit_Node* Create(Bit_Node *root){int val;scanf("%d", &val);if(-1 == val){return NULL;}root = (Bit_Node*)malloc(SIZE);root->key = val;root->l_child = Create(root->l_child);root->r_child = Create(root->r_child);return root; }

前序遍歷

遞歸解法

遞歸解法實際上就是按照前序遍歷的定義來操作。

void Preorder_Recursion_Version(Bit_Node *root){if(NULL == root){return;}printf("%d ", root->key);Preorder_Recursion_Version(root->l_child);Preorder_Recursion_Version(root->r_child); }

非遞歸解法1

通過循環模擬一層接一層的遞歸調用,用堆棧來存儲,每次循環取棧頂元素,相當于每次遞歸函數開頭訪問子樹根節點,然后依次push該根節點的右子樹和左子樹,之所以是這樣的順序是因為堆棧是FILO的形式,所以為了在之后每次循環過程中模擬遞歸調用先訪問左子樹再訪問右子樹的順序,就要按照這樣的push順序,最終變成空棧時就相當于遞歸最后返回整棵樹的根節點。

void Preorder_Stack_Version(Bit_Node *root){Bit_Node* stack[MAX];Bit_Node* tmp;int top = -1;if(NULL == root){return;}stack[++top] = root;while(-1 != top){printf("%d ", stack[top]->key);tmp = stack[top--];if(NULL != tmp->r_child){stack[++top] = tmp->r_child;}if(NULL != tmp->l_child){stack[++top] = tmp->l_child;}} }

非遞歸解法2

這個比較簡單,看了后面的中序遍歷非遞歸解法這個前序的就很好理解了。

void Preorder_Stack_Version_2(Bit_Node *root){Bit_Node* Stack[MAX];int top = -1;while(-1 != top||NULL != root){while(NULL != root){Stack[++top] = root;printf("%d ", root->key);root = root->l_child;}root = Stack[top--]->r_child;} }

中序遍歷

遞歸解法

void Inorder_Recursion_Version(Bit_Node *root){if(NULL == root){return;}Inorder_Recursion_Version(root->l_child);printf("%d ", root->key);Inorder_Recursion_Version(root->r_child); }

非遞歸解法

非遞歸解法也是用循環實現,在外層循環開始首先嵌套一個小循環,用于模擬遞歸調用不斷向左子樹訪問的過程(因為中序遍歷一棵樹是以中序的形式先遍歷左子樹的),這個內層循環直至左子樹為空時結束,然后再取棧頂元素訪問,相當于遞歸函數中訪問某一層子樹的根節點,最后再將變量root賦值為右子樹的值,以便再下個外層循環中以中序的方式訪問右子樹(模擬遞歸函數中最后遞歸訪問右子樹的過程),而這里有一個注意點,就是在遍歷從右子樹返回時,必須避免下一個外層循環對左子樹進行重復遍歷(因為這個時候實際上已經退回到了包含當前右子樹的根節點,下一個外層循環開始時先執行的是內層循環對左子樹的遍歷),需要使root值為NULL,這樣內層循環的條件就不會被觸發,而恰好從右子樹返回時root的值就是右子樹的最后一個NULL節點,這樣就避免了重復訪問。最后提一下,在外層循環中NULL != root是因為在對整棵樹的左子樹遍歷完了之后,棧為空而root非空,遍歷完整棵樹后root和棧才均為非空,單純通過棧為空或者root為空是無法遍歷整棵樹的。

void Inorder_Stack_Version(Bit_Node *root){Bit_Node* Stack[MAX];int top = -1;while(-1 != top||NULL != root){while(NULL != root){Stack[++top] = root;root = root->l_child;}root = Stack[top--];printf("%d ", root->key);root = root->r_child;} }

后序遍歷

遞歸解法

void Postorder_Recursion_Version(Bit_Node *root){if(NULL == root){return;}Postorder_Recursion_Version(root->l_child);Postorder_Recursion_Version(root->r_child);printf("%d ", root->key); }

非遞歸解法

這個非遞歸解法與中序遍歷的差不多,唯一不同的是在從右子樹返回包含該右子樹的根節點時,需要避免內層循環對左子樹的重復訪問的同時,還要避免對當前右子樹的重復訪問(因為此時相當于退回到了包含當前右子樹的根節點,這樣下一個外層循環中仍會對左右子樹進行訪問),所以這個時候進行兩個操作,一個是將root賦值為NULL避免觸發內層循環訪問左子樹(后序遍歷從右子樹返回時root值不是NULL,需自己賦值),二是標記右子樹返回時訪問的最后一個節點,這樣可以避免對右子樹的重復訪問。

void Postorder_Stack_Version(Bit_Node *root){Bit_Node* Stack[MAX];Bit_Node* visit = NULL;int top = -1;while(top != -1||NULL != root){while(NULL != root){Stack[++top] = root;root = root->l_child;}root = Stack[top];if(NULL != root->r_child&&visit != root->r_child){root = root->r_child;}else{printf("%d ", root->key);visit = root;root = NULL;top--;}} }

層序遍歷

其實就是BFS,BFS在二叉樹中運用很多,特別是不能采用遞歸的時候。

void Levelorder(Bit_Node *root, int size){Bit_Node* Q[size];int i, tail = 1;if(NULL == root){return;}Q[0] = root;for(i = 0; i < size; i++){printf("%d ", Q[i]->key);if(NULL != Q[i]->l_child){Q[tail++] = Q[i]->l_child;}if(NULL != Q[i]->r_child){Q[tail++] = Q[i]->r_child;}} }

接下來依次是計算節點數,計算葉子數,計算某一層的節點數,計算某一節點高度的遞歸解法,這些都很簡單,就不做說明了,它們的非遞歸解法其實就是BFS……于是我就懶得寫了。

int Get_Node_Sum(Bit_Node *root){if(NULL == root){return 0;}return Get_Node_Sum(root->l_child) + Get_Node_Sum(root->r_child) + 1; }int Get_Leaves_Sum(Bit_Node *root){if(NULL == root)return 0;if(NULL == root->l_child&&NULL == root->r_child){return 1;}return Get_Leaves_Sum(root->l_child) + Get_Leaves_Sum(root->r_child); }int Get_Level_Node_Sum(Bit_Node *root, int level){if(NULL == root){return 0;}if(0 == level){return 1;}return Get_Level_Node_Sum(root->l_child, level - 1) + Get_Level_Node_Sum(root->r_child, level - 1); }int Get_Height(Bit_Node *root){if(NULL == root){return -1;}return Max(Get_Height(root->l_child), Get_Height(root->r_child)) + 1; }

求最低共同祖先節點

遞歸解法1

首先這里要明確一點就是給定的兩個節點一定是分別位于公共祖先節點的左右子樹,或其中一個是最低公共祖先節點,另一個位于某一子樹。因此可以這么定義函數,每次傳入需要搜索的根節點以及給定的兩個節點,如果根節點即為給定的節點之一,則返回該節點值,如果根節點為NULL則返回NULL,表示沒有找到給定節點。均不符合則遞歸調用自身繼續搜索根節點的左右子樹,此時遞歸調用必然會返回值,可以想見如果給定節點分別在左右子樹中,則兩個遞歸調用的函數均會返回指向給定節點的指針,即返回值均為非空,那么此時的根節點即為最低公共祖先節點,將其返回;返回值為NULL則表示給定節點均不在某一子樹中,要么給定的兩個節點均在另一棵子樹中,且公共祖先節點也在另一棵子樹中,此時最低公共祖先節點已經作為返回值返回,所以直接將非空的返回值繼續返回即可,要么只有一個給定的節點在另一棵子樹中,此時指向該節點的值已經作為返回值返回,直接將這個值繼續返回即可。也就是說函數遞歸調用中實現:在訪問最低公共祖先節點與給定節點之間路徑上的節點時返回值為指向給定節點的指針,在訪問整棵樹的根節點與最低公共祖先節點之間路徑上的節點時返回最低公共祖先節點。

Bit_Node* Get_LCA_Recursion_Version(Bit_Node *root, int val_1, int val_2){Bit_Node *left, *right;if(NULL == root)return NULL;if(root->key == val_1||root->key == val_2){return root;}left = Get_LCA_Recursion_Version(root->l_child, val_1, val_2);right = Get_LCA_Recursion_Version(root->r_child, val_1, val_2);if(NULL == left)return right;if(NULL == right)return left;return root; }

遞歸解法2

在搜索節點時保留搜索路徑,然后再比較路徑上的相同節點。

int Find_Node(Bit_Node *root, int val, Bit_Node* path[]){if(NULL == root)return 0;path[++top] = root;if(val == root->key)return 1;if(1 == Find_Node(root->l_child, val, path)||Find_Node(root->r_child, val, path)){return 1;}top--;return 0; }Bit_Node* Get_LCA_Recursion_Version_2(Bit_Node *root, int val_1, int val_2){Bit_Node* path_1[MAX], *path_2[MAX];int i;top = -1;Find_Node(root, val_1, path_1);top = -1;Find_Node(root, val_2, path_2);for(i = 0; i < 100; i++){if(path_1[i]->key != path_2[i]->key){break;}}return path_1[i - 1]; }

求兩節點間距離

這題就是先求LCA然后分別求出root到給定節點和LCA的距離,最后用公式Dis(val_1) + Dis(val_2) - 2 * Dis(LCA)求出距離就好了。

int Find_Node_Level(Bit_Node *root, int val){int level;if(NULL == root)return -1;if(root->key == val)return 0;level = Find_Node_Level(root->l_child, val);if(-1 == level){level = Find_Node_Level(root->r_child, val);}if(-1 != level){return level + 1;}return -1; }int Get_Distance(Bit_Node *root, int val_1, int val_2){Bit_Node *LCA = Get_LCA_Recursion_Version(root, val_1, val_2);int level_LCA = Find_Node_Level(root, LCA->key);int level_val_1 = Find_Node_Level(root, val_1);int level_val_2 = Find_Node_Level(root, val_2);return level_val_1 + level_val_2 - 2 * level_LCA; }

判斷同構

遞歸解法很簡單,非遞歸的話任何一種遍歷都可以吧(層序就先比較根節點然后每次比較隊列首元素的兒子是不是一樣)。

int Is_Isomorphic(Bit_Node *root_1, Bit_Node *root_2){if(NULL == root_1&&NULL == root_2)return 1;if(NULL == root_1||NULL == root_2)return 0;if(root_1->key != root_2->key)return 0;return Is_Isomorphic(root_1->l_child, root_2->l_child)&&Is_Isomorphic(root_1->r_child, root_2->r_child); }

判斷完全二叉樹

感覺遞歸解這個好煩啊,不過也是因為我太菜的緣故,非遞歸的話就用BFS(感覺二叉樹的非遞歸操作很多BFS),只要知道一點,完全二叉樹BFS遍歷節點時,只要遍歷的節點有一個兒子(只能是右兒子)是NULL,或者兩個都是NULL,后面所有遍歷的節點均必須是葉節點,否則就不是CBT。

int Is_CBT(Bit_Node *root, int size){Bit_Node* Q[size];int i, tail = 1, flag = 0;if(NULL == root){return 1;}Q[0] = root;for(i = 0; i < size; i++){if(1 == flag&&(NULL != Q[i]->l_child||NULL != Q[i]->r_child)){return 0;}if(NULL == Q[i]->r_child){flag = 1;}if(NULL != Q[i]->l_child){Q[tail++] = Q[i]->l_child;}if(NULL != Q[i]->r_child){Q[tail++] = Q[i]->r_child;}}return 1; }

由前中序遍歷數列重建二叉樹

前序數列首項為根節點,后面依次是左子樹和右子樹的前序遍歷數列,而在中序數列中找到根節點后左邊的子列是左子樹的中序數列,右邊是右子樹的,因此傳入前中序數列的首地址和樹的大小,每次取前序數列的首項建立根節點,然后在中序數列中找到根節點后可以知道左右子樹的大小,就可以從前序數列中劃分分對應左右子樹的子列,再將左右子樹的相應的前中序遍歷數列的首地址和子樹大小傳入遞歸調用函數中并返回左右子樹的根節點。中后序遍歷的重建也差不多。

Bit_Node* Pre_In_Rebuild(int a_preorder[], int a_inorder[], int size){Bit_Node *root = (Bit_Node*)malloc(SIZE);int i;if(0 == size)return NULL;root->key = a_preorder[0];for(i = 0; i < size; i++){if(a_inorder[i] == a_preorder[0])break;}root->l_child = Pre_In_Rebuild(a_preorder + 1, a_inorder, i);root->r_child = Pre_In_Rebuild(a_preorder + i + 1, a_inorder + i + 1, size - i - 1);return root; }Bit_Node* In_Post_Rrebuild(int a_inorder[], int a_postorder[], int size){Bit_Node *root = (Bit_Node*)malloc(SIZE);int i;if(0 == size)return NULL;root->key = a_postorder[size - 1];for(i = 0; i < size; i++){if(root->key == a_inorder[i]){break;}}root->l_child = In_Post_Rrebuild(a_inorder, a_postorder, i);root->r_child = In_Post_Rrebuild(a_inorder + i + 1, a_postorder + i, size - i - 1);return root; }

判斷AVL樹

這個就是中序遍歷然后看看是不是遞增數列就好了,在遍歷的時候比較會節約時間和空間,當然要注意高度什么的,判斷BST就更簡單啦。

int Is_AVL(Bit_Node *root){Bit_Node* stack[MAX];int top = -1;Bit_Node *pre_node = NULL;if(NULL == root){return 1;}while(top != -1||NULL != root){while(NULL != root){stack[++top] = root;root = root->l_child;}root = stack[top--];if(NULL != pre_node&&pre_node->key >= root->key)return 0;if(abs(Get_Height(root->l_child) - Get_Height(root->r_child)) > 1)return 0;pre_node = root;root = root->r_child;}return 1; }

現在想到差不多就這些了……各種期中考orz,以后再補充了。

下面是測試代碼,說實話我也沒測過幾組,歡迎提供測試數據,報bug和優化。

1 // 2 // main.c 3 // Binary Tree 4 // 5 // Created by 余南龍 on 2016/10/20. 6 // Copyright ? 2016年 余南龍. All rights reserved. 7 // 8 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <math.h> 12 13 #define TYPE int 14 #define MAX 100 15 16 typedef struct node Bit_Node; 17 struct node{ 18 TYPE key; 19 struct node *l_child, *r_child; 20 }; 21 22 #define SIZE sizeof(Bit_Node) 23 24 int top; 25 26 int Max(int a, int b){ 27 if(a > b) 28 return a; 29 return b; 30 } 31 32 Bit_Node* Create(Bit_Node *root){ 33 int val; 34 35 scanf("%d", &val); 36 if(-1 == val){ 37 return NULL; 38 } 39 root = (Bit_Node*)malloc(SIZE); 40 root->key = val; 41 root->l_child = Create(root->l_child); 42 root->r_child = Create(root->r_child); 43 return root; 44 } 45 46 void Preorder_Recursion_Version(Bit_Node *root){ 47 if(NULL == root){ 48 return; 49 } 50 printf("%d ", root->key); 51 Preorder_Recursion_Version(root->l_child); 52 Preorder_Recursion_Version(root->r_child); 53 } 54 55 void Preorder_Stack_Version(Bit_Node *root){ 56 Bit_Node* stack[MAX]; 57 Bit_Node* tmp; 58 int top = -1; 59 60 if(NULL == root){ 61 return; 62 } 63 stack[++top] = root; 64 while(-1 != top){ 65 printf("%d ", stack[top]->key); 66 tmp = stack[top--]; 67 if(NULL != tmp->r_child){ 68 stack[++top] = tmp->r_child; 69 } 70 if(NULL != tmp->l_child){ 71 stack[++top] = tmp->l_child; 72 } 73 } 74 } 75 76 void Preorder_Stack_Version_2(Bit_Node *root){ 77 Bit_Node* Stack[MAX]; 78 int top = -1; 79 80 while(-1 != top||NULL != root){ 81 while(NULL != root){ 82 Stack[++top] = root; 83 printf("%d ", root->key); 84 root = root->l_child; 85 } 86 root = Stack[top--]->r_child; 87 } 88 } 89 90 void Inorder_Recursion_Version(Bit_Node *root){ 91 if(NULL == root){ 92 return; 93 } 94 Inorder_Recursion_Version(root->l_child); 95 printf("%d ", root->key); 96 Inorder_Recursion_Version(root->r_child); 97 } 98 99 void Inorder_Stack_Version(Bit_Node *root){ 100 Bit_Node* Stack[MAX]; 101 int top = -1; 102 103 while(-1 != top||NULL != root){ 104 while(NULL != root){ 105 Stack[++top] = root; 106 root = root->l_child; 107 } 108 root = Stack[top--]; 109 printf("%d ", root->key); 110 root = root->r_child; 111 } 112 } 113 114 void Postorder_Recursion_Version(Bit_Node *root){ 115 if(NULL == root){ 116 return; 117 } 118 Postorder_Recursion_Version(root->l_child); 119 Postorder_Recursion_Version(root->r_child); 120 printf("%d ", root->key); 121 } 122 123 void Postorder_Stack_Version(Bit_Node *root){ 124 Bit_Node* Stack[MAX]; 125 Bit_Node* visit = NULL; 126 int top = -1; 127 128 while(top != -1||NULL != root){ 129 while(NULL != root){ 130 Stack[++top] = root; 131 root = root->l_child; 132 } 133 root = Stack[top]; 134 if(NULL != root->r_child&&visit != root->r_child){ 135 root = root->r_child; 136 } 137 else{ 138 printf("%d ", root->key); 139 visit = root; 140 root = NULL; 141 top--; 142 } 143 } 144 } 145 146 void Levelorder(Bit_Node *root, int size){ 147 Bit_Node* Q[size]; 148 int i, tail = 1; 149 150 if(NULL == root){ 151 return; 152 } 153 Q[0] = root; 154 for(i = 0; i < size; i++){ 155 printf("%d ", Q[i]->key); 156 if(NULL != Q[i]->l_child){ 157 Q[tail++] = Q[i]->l_child; 158 } 159 if(NULL != Q[i]->r_child){ 160 Q[tail++] = Q[i]->r_child; 161 } 162 } 163 } 164 165 int Get_Node_Sum(Bit_Node *root){ 166 if(NULL == root){ 167 return 0; 168 } 169 return Get_Node_Sum(root->l_child) + Get_Node_Sum(root->r_child) + 1; 170 } 171 172 int Get_Leaves_Sum(Bit_Node *root){ 173 if(NULL == root) 174 return 0; 175 if(NULL == root->l_child&&NULL == root->r_child){ 176 return 1; 177 } 178 return Get_Leaves_Sum(root->l_child) + Get_Leaves_Sum(root->r_child); 179 } 180 181 int Get_Level_Node_Sum(Bit_Node *root, int level){ 182 if(NULL == root){ 183 return 0; 184 } 185 if(0 == level){ 186 return 1; 187 } 188 return Get_Level_Node_Sum(root->l_child, level - 1) + Get_Level_Node_Sum(root->r_child, level - 1); 189 } 190 191 int Get_Height(Bit_Node *root){ 192 if(NULL == root){ 193 return -1; 194 } 195 return Max(Get_Height(root->l_child), Get_Height(root->r_child)) + 1; 196 } 197 198 Bit_Node* Get_Mirror(Bit_Node *root){ 199 Bit_Node *tmp; 200 201 if(NULL == root){ 202 return NULL; 203 } 204 tmp = Get_Mirror(root->l_child); 205 root->l_child = Get_Mirror(root->r_child); 206 root->r_child = tmp; 207 return root; 208 } 209 210 Bit_Node* Get_LCA_Recursion_Version(Bit_Node *root, int val_1, int val_2){ 211 Bit_Node *left, *right; 212 213 if(NULL == root) 214 return NULL; 215 if(root->key == val_1||root->key == val_2){ 216 return root; 217 } 218 left = Get_LCA_Recursion_Version(root->l_child, val_1, val_2); 219 right = Get_LCA_Recursion_Version(root->r_child, val_1, val_2); 220 if(NULL == left) 221 return right; 222 if(NULL == right) 223 return left; 224 return root; 225 } 226 227 int Find_Node(Bit_Node *root, int val, Bit_Node* path[]){ 228 if(NULL == root) 229 return 0; 230 path[++top] = root; 231 if(val == root->key) 232 return 1; 233 if(1 == Find_Node(root->l_child, val, path)||Find_Node(root->r_child, val, path)){ 234 return 1; 235 } 236 top--; 237 return 0; 238 } 239 240 Bit_Node* Get_LCA_Recursion_Version_2(Bit_Node *root, int val_1, int val_2){ 241 Bit_Node* path_1[MAX], *path_2[MAX]; 242 int i; 243 244 top = -1; 245 Find_Node(root, val_1, path_1); 246 top = -1; 247 Find_Node(root, val_2, path_2); 248 for(i = 0; i < 100; i++){ 249 if(path_1[i]->key != path_2[i]->key){ 250 break; 251 } 252 } 253 return path_1[i - 1]; 254 } 255 256 int Find_Node_Level(Bit_Node *root, int val){ 257 int level; 258 259 if(NULL == root) 260 return -1; 261 if(root->key == val) 262 return 0; 263 level = Find_Node_Level(root->l_child, val); 264 if(-1 == level){ 265 level = Find_Node_Level(root->r_child, val); 266 } 267 if(-1 != level){ 268 return level + 1; 269 } 270 return -1; 271 } 272 273 int Get_Distance(Bit_Node *root, int val_1, int val_2){ 274 Bit_Node *LCA = Get_LCA_Recursion_Version(root, val_1, val_2); 275 int level_LCA = Find_Node_Level(root, LCA->key); 276 int level_val_1 = Find_Node_Level(root, val_1); 277 int level_val_2 = Find_Node_Level(root, val_2); 278 279 return level_val_1 + level_val_2 - 2 * level_LCA; 280 } 281 282 int Is_Isomorphic(Bit_Node *root_1, Bit_Node *root_2){ 283 if(NULL == root_1&&NULL == root_2) 284 return 1; 285 if(NULL == root_1||NULL == root_2) 286 return 0; 287 if(root_1->key != root_2->key) 288 return 0; 289 return Is_Isomorphic(root_1->l_child, root_2->l_child)&&Is_Isomorphic(root_1->r_child, root_2->r_child); 290 } 291 292 int Is_AVL(Bit_Node *root){ 293 Bit_Node* stack[MAX]; 294 int top = -1; 295 Bit_Node *pre_node = NULL; 296 297 if(NULL == root){ 298 return 1; 299 } 300 301 while(top != -1||NULL != root){ 302 while(NULL != root){ 303 stack[++top] = root; 304 root = root->l_child; 305 } 306 root = stack[top--]; 307 if(NULL != pre_node&&pre_node->key >= root->key) 308 return 0; 309 if(abs(Get_Height(root->l_child) - Get_Height(root->r_child)) > 1) 310 return 0; 311 pre_node = root; 312 root = root->r_child; 313 } 314 return 1; 315 } 316 317 int Is_CBT(Bit_Node *root, int size){ 318 Bit_Node* Q[size]; 319 int i, tail = 1, flag = 0; 320 321 if(NULL == root){ 322 return 1; 323 } 324 Q[0] = root; 325 for(i = 0; i < size; i++){ 326 if(1 == flag&&(NULL != Q[i]->l_child||NULL != Q[i]->r_child)){ 327 return 0; 328 } 329 if(NULL == Q[i]->r_child){ 330 flag = 1; 331 } 332 if(NULL != Q[i]->l_child){ 333 Q[tail++] = Q[i]->l_child; 334 } 335 if(NULL != Q[i]->r_child){ 336 Q[tail++] = Q[i]->r_child; 337 } 338 } 339 return 1; 340 } 341 342 Bit_Node* Pre_In_Rebuild(int a_preorder[], int a_inorder[], int size){ 343 Bit_Node *root = (Bit_Node*)malloc(SIZE); 344 int i; 345 346 if(0 == size) 347 return NULL; 348 root->key = a_preorder[0]; 349 for(i = 0; i < size; i++){ 350 if(a_inorder[i] == a_preorder[0]) 351 break; 352 } 353 root->l_child = Pre_In_Rebuild(a_preorder + 1, a_inorder, i); 354 root->r_child = Pre_In_Rebuild(a_preorder + i + 1, a_inorder + i + 1, size - i - 1); 355 return root; 356 } 357 358 Bit_Node* In_Post_Rrebuild(int a_inorder[], int a_postorder[], int size){ 359 Bit_Node *root = (Bit_Node*)malloc(SIZE); 360 int i; 361 362 if(0 == size) 363 return NULL; 364 root->key = a_postorder[size - 1]; 365 for(i = 0; i < size; i++){ 366 if(root->key == a_inorder[i]){ 367 break; 368 } 369 } 370 root->l_child = In_Post_Rrebuild(a_inorder, a_postorder, i); 371 root->r_child = In_Post_Rrebuild(a_inorder + i + 1, a_postorder + i, size - i - 1); 372 return root; 373 } 374 /* 375 The main function is used as a test program 376 */ 377 int main(){ 378 Bit_Node *T1 = NULL, *T2 = NULL, *T3, *T4, *LCA; 379 int size, level, val, i, val_1, val_2, distance; 380 int a_preorder[MAX], a_inorder[MAX], a_postorder[MAX]; 381 382 printf("Create a tree in preorder and use -1 as NULL:\n"); 383 T1 = Create(T1); 384 Preorder_Recursion_Version(T1); 385 putchar('\n'); 386 Preorder_Stack_Version(T1); 387 putchar('\n'); 388 Preorder_Stack_Version_2(T1); 389 putchar('\n'); 390 Inorder_Recursion_Version(T1); 391 putchar('\n'); 392 Inorder_Stack_Version(T1); 393 putchar('\n'); 394 Postorder_Recursion_Version(T1); 395 putchar('\n'); 396 Postorder_Stack_Version(T1); 397 putchar('\n'); 398 size = Get_Node_Sum(T1); 399 Levelorder(T1, size); 400 putchar('\n'); 401 printf("The number of leaves is %d\n", Get_Leaves_Sum(T1)); 402 printf("Which level's node sum do you want to know:"); 403 scanf("%d", &level); 404 printf("The number of nodes of level %d is %d\n", level, Get_Level_Node_Sum(T1, level)); 405 printf("The LCA of which two nodes do you want to know?\n"); 406 scanf("%d%d", &val_1, &val_2); 407 LCA = Get_LCA_Recursion_Version(T1, val_1, val_2); 408 if(NULL != LCA){ 409 printf("%d\n", LCA->key); 410 } 411 LCA = Get_LCA_Recursion_Version_2(T1, val_1, val_2); 412 if(NULL != LCA){ 413 printf("%d\n", LCA->key); 414 } 415 printf("The distance between which two nodes do you want to know?\n"); 416 scanf("%d%d", &val_1, &val_2); 417 distance = Get_Distance(T1, val_1, val_2); 418 printf("%d\n", distance); 419 printf("Get Mirror of the current tree.\n"); 420 T1 = Get_Mirror(T1); 421 Preorder_Recursion_Version(T1); 422 putchar('\n'); 423 Inorder_Recursion_Version(T1); 424 putchar('\n'); 425 T1 = Get_Mirror(T1); 426 printf("Create another tree:\n"); 427 T2 = Create(T2); 428 printf("Is two trees isomorphic? %d\n", Is_Isomorphic(T1, T2)); 429 printf("Is new tree an AVL tree? %d\n", Is_AVL(T2)); 430 printf("Is new tree a CBT? %d\n", Is_CBT(T2, size)); 431 printf("Input the array of a tree in preorder and use -1 as an end:\n"); 432 for(i = 0; i < MAX; i++){ 433 scanf("%d", &val); 434 if(-1 != val){ 435 a_preorder[i] = val; 436 } 437 else{ 438 break; 439 } 440 } 441 printf("Input the array of a tree in inorder and use -1 as an end:\n"); 442 for(i = 0; i < MAX; i++){ 443 scanf("%d", &val); 444 if(-1 != val){ 445 a_inorder[i] = val; 446 } 447 else{ 448 break; 449 } 450 } 451 T3 = Pre_In_Rebuild(a_preorder, a_inorder, i); 452 Preorder_Recursion_Version(T3); 453 putchar('\n'); 454 Inorder_Recursion_Version(T3); 455 putchar('\n'); 456 Postorder_Recursion_Version(T3); 457 putchar('\n'); 458 printf("Input the array of a tree in inorder and use -1 as an end:\n"); 459 for(i = 0; i < MAX; i++){ 460 scanf("%d", &val); 461 if(-1 != val){ 462 a_inorder[i] = val; 463 } 464 else{ 465 break; 466 } 467 } 468 printf("Input the array of a tree in postorder and use -1 as an end:\n"); 469 for(i = 0; i < MAX; i++){ 470 scanf("%d", &val); 471 if(-1 != val){ 472 a_postorder[i] = val; 473 } 474 else{ 475 break; 476 } 477 } 478 T4 = In_Post_Rrebuild(a_inorder, a_postorder, i); 479 Preorder_Recursion_Version(T4); 480 putchar('\n'); 481 Inorder_Recursion_Version(T4); 482 putchar('\n'); 483 Postorder_Recursion_Version(T4); 484 putchar('\n'); 485 return 0; 486 }

?

?

轉載于:https://www.cnblogs.com/YuNanlong/p/6003663.html

總結

以上是生活随笔為你收集整理的二叉树操作整理的全部內容,希望文章能夠幫你解決所遇到的問題。

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