BTree.h (結構定義, 基本操做, 遍歷)算法
1 #define MS 10 2 3 typedef struct BTreeNode{ 4 char data; 5 struct BTreeNode * left 6 struct BTreeNode * right; 7 }BTreeNode; 8 9 10 BTreeNode* InitBTree(); 11 /*初始化二叉樹,即把樹根指針置空*/ 12 BTreeNode* CreateBtree(char *a); 13 /*根據a所指向的二叉樹廣義表字符串創建對應的存儲結構,返回樹根指針*/ 14 int BTreeEmpty(BTreeNode* BT); 15 /*判斷一顆二叉樹是否爲空,如果則返回1,不然返回0*/ 16 void Preorder(BTreeNode * BT); 17 /*先序遍歷的遞歸算法*/ 18 void Inorder(BTreeNode * BT); 19 /*中序遍歷的地鬼算法*/ 20 void Postorder(BTreeNode * BT); 21 /*後序遍歷的遞歸算法*/ 22 void Levelorder(BTreeNode* BT); 23 /*按層遍歷由BT指針所指向的二叉樹*/ 24 void Inorder(BTreeNode* BT); 25 /*對二叉樹進行中序遍歷的非遞歸算法*/ 26 int BTreeDepth(BTreeNode * BT); 27 /*求BT指向的一顆二叉樹深度*/ 28 char* FindBTree(BTreeNode * BT, char x); 29 /*從BT所指向的二叉樹中查找值爲x的節點*/ 30 void PrintBTree(BTreeNode* BT); 31 /*輸出二叉樹的廣義表表示*/ 32 BTreeNode* ClearBTree(BTreeNode* BT); 33 /*清除二叉樹中的全部節點,使之成爲一顆空樹*/
BTree.c (二叉樹的接口實現)數組
1 void Preorder(BTreeNode * BT){ 2 3 if(BT != NULL){ 4 putchar(BT->data); //訪問根節點 5 Preorder(BT->left); //先序遍歷左子樹 6 Preorder(BT->right); //先序遍歷右子樹 7 } 8 } 9 10 void Inorder(BTreeNode * BT){ 11 if(BT != NULL){ 12 Inorder(BT->left); //中序遍歷左子樹 13 putchar(BT->data); //訪問根節點 14 Inoreder(BT->right); //中序遍歷右子樹 15 } 16 } 17 18 void InorderN(BTreeNode* BT){ 19 /*對二叉樹進行中序遍歷的非遞歸算法*/ 20 BTreeNode* s[10]; //定義用於存儲節點指針的棧 21 int top = -1; //定義棧頂指針並賦初值使s棧爲空 22 BTreeNode* p = BT; //定義指針p並使樹根指針爲它的初值 23 while(top != -1 || p != NULL){ 24 /*當棧非空或p指針非空時執行循環*/ 25 while(p != NULL){ 26 /*依次向下訪問左子樹並使樹根指針進棧*/ 27 top++; 28 s[top] = p; 29 p = p->left; 30 } 31 if(top != -1){ 32 /*樹根指針出棧並輸出節點的值,接着訪問右子樹*/ 33 p = s[top]; 34 top--; 35 putchar(p->data); 36 p = p->right; 37 } 38 } 39 } 40 void Postorder(BTreeNode * BT){ 41 if(BT != NULL){ 42 Postorder(BT->left); //後序遍歷左子樹 43 Postorder(BT->right); //後序遍歷右子樹 44 putchar(BT->data); //訪問根節點 45 } 46 } 47 void Levelorder(BTreeNode* BT){ 48 /*按層遍歷由BT指針所指向的二叉樹*/ 49 /*定義隊列所使用的數組空間,元素類型爲指向節點的指針類型*/ 50 BTreeNode* q[MS]; //MS爲事先定義的符號常量 51 /*定義隊首指針和隊尾指針,初始均置0表示空隊*/ 52 int front = 0, rear = 0; 53 /*將樹根指針進隊*/ 54 if(BT != NULL) 55 rear = (rear + 1) % MS; 56 q[rear] = BT; 57 } 58 /*當隊列非空時執行循環*/ 59 while(front !- rear){ 60 BTreeNode* p; //定義指針變量p 61 /*使隊首指針指向隊首 62 BTreeNode* InitBTree(){ 63 /*初始化二叉樹,即把樹根指針置空*/ 64 return NULL; 65 } 66 67 BTreeNode* CreateBtree(char *a){ 68 /*根據a所指向的二叉樹廣義表字符串創建對應的存儲結構,返回樹根指針*/ 69 BTreeNode * p = NULL; 70 /*定義S數組做爲存儲根節點指針的棧使用*/ 71 BTreeNode* S[MS]; //MS事先定義的符號常量 72 /*定義top做爲S棧的棧頂指針,初值爲-1,表示空棧*/ 73 int top = -1; 74 /*用k做爲處理節點的左子樹和右子樹的標記,k=1處理左子樹,k=2處理右子樹*/ 75 int k; 76 /*用i掃描數組a中存儲的二叉樹廣義表字符串,初值爲0*/ 77 int i = 0; 78 /*把樹根指針置爲空,即從空樹開始創建二叉樹,待創建二叉樹結束後返回*/ 79 BTreeNode BT = NULL; 80 /*每循環一次處理一個字符,知道掃描到字符串結束符'\0’爲止*/ 81 while(a[i]){ 82 switch(a[i]){ 83 case ' ':/*對空格不作任何處理,退出此switch語句*/ 84 case '(': 85 if(top == MS-1){ 86 printf("棧空間過小,需增長MS的值!\n"); 87 exit(1); 88 } 89 if(p == NULL){ 90 printf("p值不能爲空,退出程序!\n"); 91 exit(1); 92 } 93 top++; 94 s[top] = p; 95 k = 1; 96 p = NULL; 97 break; 98 case ')': 99 if(top == -1){ 100 printf("二叉樹廣義表字符串有錯!\n"); 101 exit(1); 102 } 103 top--; 104 break; 105 case ',': 106 k = 2; 107 break; 108 default: 109 if((a[i] >= 'a' && a[i] <= 'z' || a[i] >= 'A' && a[i] <= 'Z')){ 110 p = malloc(sizeof(BTreeNode)); 111 p->data = a[i]; 112 p->left = p->right = NULL; 113 if(BT == Null) BT = P; 114 else{ 115 if(k == 1)s[top]->lef = p; 116 else s[top]->right = p; 117 } 118 } 119 else{ 120 printf("廣義表字符串出錯!\n"); 121 exit(1); 122 } 123 } 124 /*爲掃描下一個字符修改i值*/ 125 i++; 126 } 127 return BT; 128 } 129 int BTreeEmpty(BTreeNode* BT){ 130 /*判斷一顆二叉樹是否爲空,如果則返回1,不然返回0*/ 131 if(BT== NULL) return 1; 132 else return 0; 133 } 134 135 int BTreeDepth(BTreeNode * BT){ 136 /*求BT指向的一顆二叉樹深度*/ 137 if(BT != NULL) return 0; 138 else{ 139 /*計算左子樹深度*/ 140 int dep1 = BTreeDepth(BT->left); 141 /*計算右子樹深度*/ 142 int dep1 = BTreeDepth(BT->right); 143 144 /*返回樹的深度*/ 145 if(dep1 > dep2) return dep1 + 1; 146 else return dep2 + 1; 147 } 148 } 149 150 char* FindBTree(BTreeNode * BT, char x){ 151 /*從BT所指向的二叉樹中查找值爲x的節點*/ 152 if(BT == NULL) return NULL; 153 else{ 154 /*樹節點的值等於x則返回元素地址*/ 155 if(BT->data == x) return &(BT->data); 156 else{ 157 char* p; 158 /*向左子樹查找若成功則繼續返回元素的地址*/ 159 if(p = FindBTree(BT->left,x)) return p; 160 /*向右子樹查找若成功則繼續返回元素的地址*/ 161 if(p = FindBTree(BT->right,x)) return p; 162 /*左右子樹查找均失敗則返回空*/ 163 return NULL; 164 } 165 } 166 } 167 168 void PrintBTree(BTreeNode* BT){ 169 /*輸出二叉樹的廣義表表示*/ 170 /*樹爲空時天然結束遞歸,不然執行以下操做*/ 171 if(BT != NULL){ 172 /*輸出根節點的值*/ 173 putchar(BT->data); 174 /*輸出左右子樹*/ 175 if(BT->left != NULL || BT->right != NULL){ 176 putchar('('); //輸出左括號 177 PrintBTree(BT->left); //輸出左子樹 178 if(BT->right != NULL) putchar(','); //若右子樹不爲空則輸出逗號分隔符 179 180 PrintBTree(BT -> right); //輸出右子樹 181 putchar(')'); //輸出右括號 182 } 183 } 184 } 185 186 BTreeNode* ClearBTree(BTreeNode* BT){ 187 if(BT == NULL) return NULL; 188 else{ 189 ClearBTree(BT->left); //刪除左子樹 190 ClearBTree(BT->right); //刪除右子樹 191 free(BT); //釋放根節點 192 return NULL; //返回空指針 193 } 194 }
BTreeTest.c (二叉樹運算調試程序)spa
1 #include "BTree.h" 2 3 int main(void){ 4 BTreeNode *p; 5 char *k; 6 int n1; 7 char *a = "A(B(C),D(E(F,G),H(,I)))"; 8 P = InitBTree(); //創建空樹 9 p = CreateBTree(a); //按照廣義表形式的二叉樹創建二叉鏈表 10 Preorder(p); putchar('\n'); //先序遍歷 11 Inorder(p) putchar('\n'); //中序遍歷 12 Postorder(p) putchar('\n'); //後序遍歷 13 Levelorder(p) putchar('\n'); //按層遍歷 14 InorderN(p) putchar('\n'); //中序非遞歸遍歷 15 printf("%d\n",BTreeDepth(p)); //求二叉樹深度 16 k = FindBTree(p, 'I'); if(k!=NULL) printf("%c\n", *k); //查找二叉樹 17 PrintBTree(p); //輸出二叉樹 18 p = ClearBTree(p); //清空二叉樹 19 n1 = BTreeEmpty(P); printf("%d\n", n1); //判斷樹是否爲空 20 21 }