二叉鏈表表示的二叉樹以及操做若干

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 
 4 #define OK 1
 5 #define ERROR 0
 6 #define YES 1
 7 #define NO 0
 8 
 9 typedef int Status;  10 typedef char ElemType;  11 
 12 typedef struct BiTreeNode{  13  ElemType data;  14     struct BiTreeNode *lchild, *rchild;  15 }BiTreeNode, *BiTree;  16 
 17 typedef struct QueueNode{  18     BiTreeNode* binary_tree_node;        //存放的"數據"是二叉樹的節點的指針
 19     struct QueueNode* next;  20 }QueueNode, *QueueNodePtr;  21 typedef struct LinkQueue{  22  QueueNodePtr front;  23  QueueNodePtr rear;  24 }LinkQueue, *Queue;  25 
 26 
 27 //建立頭結點,初始化
 28 Status InitQueue(Queue q){    //注意這裏的參數不是Queue *q,由於不是要爲q分配空間  29                 //而是爲了q中的front和rear
 30     q->front = (QueueNode*)malloc(sizeof(struct QueueNode));  31     if( !q->front )  32         return ERROR;  33     q->rear = q->front;  34     q->front->next = NULL;  35     return OK;  36 }  37 //入隊
 38 Status EnterQueue(Queue q, BiTreeNode* binaryTreeNode){  39     QueueNode* new = (QueueNode*)malloc(sizeof(struct QueueNode));  40     if( !new )  41         return ERROR;  42     new->binary_tree_node = binaryTreeNode;  43     new->next = q->rear->next;  44     q->rear->next = new;  45     q->rear = new;  46     return OK;  47 }  48 //出隊
 49 Status DeleteQueue(Queue q, BiTreeNode** binaryTreeNode){  50     if( q->front == q->rear ){  51         printf("Queue Empty!\n");  52         return ERROR;  53  }  54  QueueNodePtr t;  55     t = q->front->next;  56     *binaryTreeNode = t->binary_tree_node;  57     q->front->next = t->next;  58     free(t);  59     if( t == q->rear )  60         q->rear = q->front;  61     return OK;  62 }  63 Status IsQueueEmpty(Queue q){  64     return q->front == q->rear ? OK : ERROR;  65 }  66 
 67 //test Queue  68 //int main(){
 69 /* 測試 1  70  * 如何爲指針分配空間,都是4?  71  * 下面的測試中出現告終構對齊的問題。  72  printf("%d\n",sizeof(ElemType));  73  printf("%d\n",sizeof(struct QueueNode*));  74  printf("%d\n",sizeof(QueueNode));  75  printf("%d\n",sizeof(QueueNodePtr));  76 
 77  printf("%d\n",sizeof(LinkQueue));  78  printf("%d\n",sizeof(Queue));  79 
 80  int *p;  81  printf("%d\n",sizeof(p));  82 */
 83 
 84 /* 測試 2 √  85  * 原來沒有寫下面這個函數,致使出錯:  86  使用指針以前請保證它有合法值。  87  main裏的三個指針都沒有合法值。(from CSDN)  88     
 89  ————————————————————————————————————————————————————————————  90  Status InitBinaryTreeNode(BiTree *T){  91  *T = (BiTreeNode*)malloc(sizeof(struct BiTreeNode));  92  if( !*T )  93  return ERROR;  94  return OK;  95  }  96  ————————————————————————————————————————————————————————————  97  LinkQueue* q;  98  InitQueue(q);  99  BiTree p; 100  InitBinaryTreeNode(&p); 101  p->data = 'a'; 102  printf("%c ",p->data); 103  BiTree t; 104  InitBinaryTreeNode(&t); 105  t->data = 'c'; 106  printf("%c ",t->data); 107 */                
108 /* 測試 3 109  LinkQueue* q; 110  InitQueue(q); 111  BiTreeNode *p,*r; 112  InitBinaryTreeNode(&p); 113  InitBinaryTreeNode(&r); 114  p->data = 'a'; 115  printf("%c \n",p->data); 116  EnterQueue(q,p); 117  DeleteQueue(q,&r); 118  printf("%c \n",r->data); 119 
120 // return OK; 121 } 122 //test Queue end 123 */
124 
125 
126 //初始化二叉樹,在要建立二叉樹以前調用
127 Status InitBiTree(BiTree *T){ 128     *T = NULL; 129     return OK; 130 } 131 //初始化二叉樹節點。單個節點使用的時候調用此函數,否則指針會成爲野指針
132 Status InitBinaryTreeNode(BiTree *T){ 133     *T = (BiTreeNode*)malloc(sizeof(struct BiTreeNode)); 134     if( !*T ) 135         return ERROR; 136     return OK; 137 } 138 //使用前序遍歷的結構進行二叉樹的建立
139 Status CreateBiTree_PreOrder(BiTree* T){ 140  ElemType c; 141     scanf("%c", &c); 142     if( ' ' == c ){ 143         *T = NULL; 144  } 145     else{ 146         *T = (BiTree)malloc(sizeof(struct BiTreeNode)); 147         if( !*T ) 148             return ERROR; 149         (*T)->data = c; 150         CreateBiTree_PreOrder(&(*T)->lchild); 151         CreateBiTree_PreOrder(&(*T)->rchild); 152  } 153     return OK; 154 } 155 void visit(ElemType c,int level){ 156     printf(" %c level is:%d\n", c, level); 157 } 158 void visit_2(ElemType c){ 159     printf("%c ", c); 160 } 161         //遞歸的前序遍歷二叉樹
162 Status PreOrderTraverse(BiTree T,int level){ 163     if( T ){ 164         visit(T->data,level); 165         PreOrderTraverse(T->lchild,level + 1); 166         PreOrderTraverse(T->rchild,level + 1); 167  } 168     return OK; 169 } 170         //遞歸的中序遍歷二叉樹
171 Status InOrderTraverse(BiTree T,int level){ 172     if( T ){ 173         InOrderTraverse(T->lchild,level + 1); 174         visit(T->data,level); 175         InOrderTraverse(T->rchild,level + 1); 176  } 177     return OK; 178 } 179         //遞歸的後序遍歷二叉樹
180 Status PostOrderTraverse(BiTree T,int level){ 181     if( T ){ 182         PostOrderTraverse(T->lchild,level + 1); 183         PostOrderTraverse(T->rchild,level + 1); 184         visit(T->data,level); 185  } 186     return OK; 187 } 188         //層序遍歷二叉樹<<非遞歸>> 189 //要進行層序遍歷須要藉助於隊列的輔助:先將二叉樹的根入隊列,而後將其 190 //出隊列,visit。若是該根有左孩子,則入隊;若是該根有右孩子,則入隊。 191 //而後出隊,對該出隊的節點進行以上的相同的訪問。直到對空
192 Status LevelOrderTraverse(BiTree T){ 193     LinkQueue *q = (LinkQueue*)malloc(sizeof(LinkQueue));    /*有幾回代碼出錯都是 194  由於這個,指針q沒有 195  指向。 196                                   */
197  InitQueue(q); 198     BiTreeNode* nodePtr; 199     InitBinaryTreeNode(&nodePtr); 200  EnterQueue(q,T); 201     while( !IsQueueEmpty(q) ){ 202         DeleteQueue(q, &nodePtr); 203         visit_2(nodePtr->data); 204         if( nodePtr->lchild != NULL ){ 205             EnterQueue(q,nodePtr->lchild); 206  } 207         if( nodePtr->rchild != NULL ){ 208             EnterQueue(q,nodePtr->rchild); 209  } 210  } 211     return OK; 212 } 213 //判斷二叉樹是否爲空
214 Status IsTreeEmpty(BiTree T){ 215     return T == NULL ? OK : ERROR; 216 } 217 //計算二叉樹的深度
218 int BiTreeDepth(BiTree T){ 219     int i = 0,j = 0; 220     if( !T ) 221         return 0; 222     if( T->lchild ) 223         i = BiTreeDepth(T->lchild); 224     else
225         i = 0; 226     if( T->rchild ) 227         j = BiTreeDepth(T->rchild); 228     else
229         j = 0; 230     return i>j ? i+1 : j+1; 231 } 232 /* 判斷一棵二叉樹是不是徹底二叉樹: 233  * 思路: 藉助於隊列,先將root入隊,當隊列不爲空的時候,出隊一個元素。若是節點不爲空, 234  * 則將該節點的左孩子和右孩子入隊;若是節點爲空,則查找後序出隊的元素中是否全 235  * 是NULL,不然就不是徹底二叉樹 236  * */
237 Status IsCompleteBinaryTree(BiTree T){ 238     Queue q = (Queue)malloc(sizeof(struct QueueNode)); 239     if( !q ) 240         return ERROR; 241  InitQueue(q); 242  BiTree node; 243     InitBinaryTreeNode(&node); 244  EnterQueue(q, T); 245     while( IsQueueEmpty(q) != OK ){ 246         DeleteQueue(q, &node); 247         if( node != NULL ){ 248             EnterQueue(q, node->lchild); 249             EnterQueue(q, node->rchild); 250  } 251         else{ 252             while( IsQueueEmpty(q) != OK ){ 253                 DeleteQueue(q, &node); 254                 if( node != NULL ) 255                     return NO; 256  } 257  } 258  } 259     return YES; 260 } 261 int main(){ 262     int level = 1; 263  BiTree BT; 264     InitBiTree(&BT); 265     if(IsTreeEmpty(BT)) 266         printf("Binary is Empty!\n"); 267     else
268         printf("Exist Element in Tree\n"); 269     printf("Create Binary Tree by PreOrder: "); 270     CreateBiTree_PreOrder(&BT); 271     printf("PreOrder Traverse: \n"); 272  PreOrderTraverse(BT,level); 273     printf("InOrder Traverse: \n"); 274  InOrderTraverse(BT,level); 275     printf("PostOrder Traverse: \n"); 276  PostOrderTraverse(BT,level); 277     printf("LevelOrder Traverse: \n"); 278  LevelOrderTraverse(BT); 279     printf("\nthe Depth of Binary is %d\n",BiTreeDepth(BT)); 280 
281     if(IsCompleteBinaryTree(BT) == YES ) 282         printf("Complete Binary Tree!\n"); 283     else
284         printf("no-Complete Binary Tree!\n"); 285     return 0; 286 }

相關文章
相關標籤/搜索