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 }