1 #include
2 #include
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 }