首先通过一张图来认识树:
树:由N(N>=0)个结点构成的集合。对N>1的树,有:
1.有一个特殊的结点,称为根结点,根结点没有前驱结点
2.除根结点外,其余结点被分为M(M>0)个互不相交的集合T1、T2…..Tm,其中每一个集合Ti(1<=i<=m)有是一颗结构与树类似的子树。每棵子树的根结点有且只有一个前驱,可以有0个或多个后继。,因此,树是递归定义的。代码实现多采用递归的思想。
二叉树的遍历:
遵循某种次序,遍历二叉树中的所有结点,使得每个结点被访问一次,而且仅访问一次。“访问”:即对根结点施行某些操作。
前序遍历:先访问根结点,再前序遍历根结点的左子树,最后前序遍历根结点的右子树。
中序遍历:先中序遍历根结点的左子树,再访问根结点,最后中序遍历根结点的右子树。
后序遍历:先后序遍历根结点的左子树,再后序遍历根结点的右子树,最后访问根结点。
层序遍历:按照二叉树的层序次序(即从根结点层到叶结点层),同一层中按先左子树再右子树的次序遍历二叉树。
例如:如下一棵树,它的前序、中序、后序、层序遍历
代码实现:
bin_tree.h
1 #pragma once
2 #include <stdio.h>
3 typedef char TreeNodeType;
4 //使用孩子表示法来表示一棵树
5 typedef struct TreeNode {
6 TreeNodeType data;
7 struct TreeNode* lchild;
8 struct TreeNode* rchild;
9 }TreeNode;
10
11 //对于链表来说,使用链表的头节点指针来表示一个链表
12 //对于二叉树来说,使用跟结点的指针来表示一棵树
13 //树的初始化
14 void TreeInit(TreeNode** pRoot);
15 //前序遍历
16 void TreePreOrder(TreeNode* root);
17 //中序遍历
18 void TreeInOrder(TreeNode* root);
19 //后序遍历
20 void TreePostOrder(TreeNode* root);
21 //层序遍历
22 void TreeLevelOrder(TreeNode* root);
23
24 //输入一个数组(数组中的每个元素就是树上的结点),根据数组的内容
25 //构建出一颗树,数组中元素的内容符合树的先序遍历结果(包含所有空结点)
26 TreeNode* TreeCreate(TreeNodeType arry[],size_t size,char null_node);
27
28 //求二叉树中结点的个数
29 size_t TreeSize(TreeNode* root);
30 //求二叉树中叶子结点的个数
31 size_t TreeLeafSize(TreeNode* root);
32 //求二叉树中第K层结点的个数
33 size_t TreeKLevelSize(TreeNode* root,int K);
34
35 //求二叉树的高度/深度
36 size_t TreeHeight(TreeNode* root);
37
38 void TreeDestroy(TreeNode* root);
39
40 //在二叉树中查找结点,给定一个数值,求出对应结点的指针
41 //假设二叉树中的结点是不重复的
42 TreeNode* TreeFind(TreeNode* root,TreeNodeType to_find);
43
44 //求出child的父节点
45 TreeNode* FindParent(TreeNode* root,TreeNode* child);
46
47 //求出当前节点的左子树和右子树
48 TreeNode* LChild(TreeNode* node);
49 TreeNode* RChild(TreeNode* node);
bin_tree.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "bin_tree.h"
4 #include "seqqueue.h"
5
6 TreeNode* CreateTreeNode(TreeNodeType value){
7 TreeNode* new_node = (TreeNode*)malloc(sizeof(TreeNode));
8 new_node->data = value;
9 new_node->lchild = NULL;
10 new_node->rchild = NULL;
11 return new_node;
12 }
13
14 void DestroyTreeNode(TreeNode* node){
15 free(node);
16 }
17
18 void TreeInit(TreeNode** pRoot){
19 if(pRoot == NULL){
20 //非法输入
21 return;
22 }
23 *pRoot = NULL;
24 return;
25 }
26
27 void TreePreOrder(TreeNode* root){
28 if(root == NULL){
29 //空树
30 return;
31 }
32 //先访问根结点,访问即打印
33 printf("%c ",root->data);
34 //然后递归的遍历左子树
35 TreePreOrder(root->lchild);
36 //最后在递归的遍历右子树
37 TreePreOrder(root->rchild);
38 return;
39 }
40
41 void TreeInOrder(TreeNode* root){
42 if(root == NULL){
43 //空树
44 return;
45 }
46 //先递归的遍历左子树
47 TreeInOrder(root->lchild);
48 //再访问根结点
49 printf("%c ",root->data);
50 //最后递归的遍历右子树
51 TreeInOrder(root->rchild);
52 return;
53 }
54
55 void TreePostOrder(TreeNode* root){
56 if(root == NULL){
57 //空树
58 return;
59 }
60 //先递归的遍历左子树
61 TreePostOrder(root->lchild);
62 //再递归的遍历右子树
63 TreePostOrder(root->rchild);
64 //最后访问根结点
65 printf("%c ",root->data);
66 return;
67 }
68
69 void TreeLevelOrder(TreeNode* root){
70 if(root == NULL){
71 //空树
72 return;
73 }
74 SeqQueue queue;
75 SeqQueueInit(&queue);
76 SeqQueuePush(&queue,root);
77 while(1){
78 SeqQueueType front;
79 int ret = SeqQueueFront(&queue,&front);
80 if(ret == 0){
81 //如果队列取队首元素失败,说明队列为空
82 //如果队列为空就说明遍历结束了
83 break;
84 }
85 //访问树中的元素,打印当前值
86 printf("%c ",front->data);
87 //把当前队首元素出队列
88 SeqQueuePop(&queue);
89 //把当前元素的左右子树入队列
90
91 if(front->lchild != NULL){
92 SeqQueuePush(&queue,front->lchild);
93 }
94 if(front->rchild != NULL){
95 SeqQueuePush(&queue,front->rchild);
96 }
97 }
98 return;
99 }
100
101 TreeNode* _TreeCreate(TreeNodeType arry[],size_t size,size_t* index,TreeNodeType null_node){
102 if(index == NULL){
103 //非法输入
104 return NULL;
105 }
106 if(*index >= size){
107 return NULL;
108 }
109 if(arry[*index] == null_node){
110 return NULL;
111 }
112 TreeNode* new_node = CreateTreeNode(arry[*index]);
113 ++(*index);
114 new_node->lchild = _TreeCreate(arry,size,index,null_node);
115 ++(*index);
116 new_node->rchild = _TreeCreate(arry,size,index,null_node);
117 return new_node;
118 }
119
120 TreeNode* TreeCreate(TreeNodeType arry[],size_t size,char null_node){
121 //表示当前取数组中的那个元素
122 size_t index = 0;
123 return _TreeCreate(arry,size,&index,null_node);
124 }
125
126 TreeNode* TreeClone(TreeNode* root){
127 if(root == NULL){
128 //空树
129 return NULL;
130 }
131 //按照先序方式来遍历
132 TreeNode* new_node = CreateTreeNode(root->data);
133 new_node->lchild = TreeClone(root->lchild);
134 new_node->rchild = TreeClone(root->rchild);
135 return new_node;
136 }
137 //销毁的过程中一定要保证左右子树能够被正确找到,所有按照后序的方式来销毁
138 void TreeDestroy(TreeNode* root){
139 if(root == NULL){
140 //空树
141 return;
142 }
143 //按照后序遍历的方式来销毁整个树
144 TreeDestroy(root->lchild);
145 TreeDestroy(root->rchild);
146 DestroyTreeNode(root);
147 return;
148 }
149
150 //方法一
151 void _TreeSize(TreeNode* root,size_t* size){
152 if(root == NULL){
153 //空树
154 return;
155 }
156 //按照前序的方式遍历,这里的访问是++
157 ++(*size);
158 _TreeSize(root->lchild,size);
159 _TreeSize(root->rchild,size);
160 }
161 size_t TreeSize(TreeNode* root){
162 size_t size = 0;
163 _TreeSize(root,&size);
164 return size;
165 }
166 //方法二
167 size_t TreeSize(TreeNode* root){
168 if(root == NULL){
169 //空树
170 return 0;
171 }
172 return 1 + TreeSize(root->lchild) + TreeSize(root->rchild);
173 }
174
175 size_t TreeLeafSize(TreeNode* root){
176 if(root == NULL){
177 //空树
178 return 0;
179 }
180 if(root->lchild == NULL && root->rchild == NULL){
181 //root是叶子结点
182 return 1;
183 }
184 //root不是叶子结点
185 return TreeLeafSize(root->lchild) + TreeLeafSize(root->rchild);
186 }
187
188 size_t TreeKLevelSize(TreeNode* root,int K){
189 if(root == NULL || K < 1){
190 //root等于空是空树,K<1是非法输入
191 return 0;
192 }
193 if(K == 1){
194 return 1;
195 }
196 return TreeKLevelSize(root->lchild ,K - 1) + TreeKLevelSize(root->rchild,K - 1);
197
198 }
199
200 size_t TreeHeight(TreeNode* root){
201 if(root == NULL){
202 //空树
203 return 0;
204 }
205 if(root->lchild == NULL && root->rchild == NULL){
206 return 1;
207 }
208 size_t lheight = TreeHeight(root->lchild);
209 size_t rheight = TreeHeight(root->rchild);
210
211 return 1 + (lheight > rheight ? lheight : rheight);
212 }
213
214 TreeNode* TreeFind(TreeNode* root,TreeNodeType to_find){
215 if(root == NULL){
216 //空树
217 return NULL;
218 }
219 if(root->data == to_find){
220 return root;
221 }
222 TreeNode* lresult = TreeFind(root->lchild,to_find);
223 TreeNode* rresult = TreeFind(root->rchild,to_find);
224 //不等于空,说明找到了
225 return lresult != NULL ? lresult : rresult;
226 }
227
228 TreeNode* FindParent(TreeNode* root,TreeNode* child){
229 if(root == NULL || child == NULL){
230 return NULL;
231 }
232 if(root->lchild == child || root->rchild == child){
233 return root;
234 }
235 TreeNode* lresult = FindParent(root->lchild,child);
236 TreeNode* rresult = FindParent(root->rchild,child);
237 return lresult != NULL ? lresult : rresult;
238 }
239
240 TreeNode* LChild(TreeNode* node){
241 if(node == NULL){
242 return NULL;
243 }
244 return node->lchild;
245 }
246
247 TreeNode* RChild(TreeNode* node){
248 if(node == NULL){
249 return NULL;
250 }
251 return node->rchild;
252 }