1. 程式人生 > >二叉樹 ADT介面 遍歷演算法 常規運算

二叉樹 ADT介面 遍歷演算法 常規運算

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 1132      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   (二叉樹運算除錯程式)

 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      }