/设树结点的元素类型为ElemType(可以为char或int),采用二叉链(或三叉链,即双亲孩子)存储,实现以下二叉树的各种基本操作的程序:
① 编写一个创建二叉树的函数,通过文件读取方式,建立不少于10个结点的二叉树T(建议用递归方式创建);√
② 给定元素x,在二叉树中查找该元素x,若找到则返回该节点的指针;√
③ 用凹入表示法打印该二叉树(可以是图8-2的形式或者8.4.3中的逆时针旋转90°,一个先序,一个中序RDL);√
④ 用非递归方式先序遍历方式输出树T的结点;(用到栈)√
⑤ 用中序或后序遍历方式输出树T的结点;√
⑥ 用层次遍历方式输出树T的结点;(用到队列)√
⑦ 输出树T的深度;√
⑧ 输出树T的叶子结点或非叶子结点;
⑨ 主函数设计菜单,通过菜单选择相应的函数调用实现以上各项操作。/
typedef struct tree {树
int number;
struct tree *first;
struct tree *rchild;
struct tree *lchild;
} bitree;
typedef struct queue {队列
bitree *data;
queue *next;
} queue;
typedef struct stack {//栈
bitree *elements[M];
int top;
} seqstack; //定义一个储存树类型地址的栈,方便遍历的时候追踪到树的地址。
主要操作算法思想或算法步骤:
a.递归:对空间和时间复杂度要求大,但对小规模树的遍历较清晰明了
b.凹型遍历:对树的结构有很清楚的体现。
c.前中后序遍历适合对树的数据位置进行掌握。
d.层次遍历和前中后序遍历分别为广度和深度之分。
层次遍历算法:采用一个队列q,先将二叉树根结点入队列,然后退队列,输出该结点;若它有左子树,便将左子树根结点入队列;若它有右子树,便将右子树根结点入队列,直到队列空为止。因为队列的特点是先进后出,所以能够达到按层次遍历二叉树的目的
1.#include <stdio.h>
2.#include <malloc.h>
3.#define M 100
4.
5.typedef struct tree {
6. int number;
7. struct tree *first;
8. struct tree *rchild;
9. struct tree *lchild;
10.} bitree;
11.
12.
13.typedef struct queue {
14. bitree *data;
15. queue *next;
16.} queue;
17.
18.typedef struct stack {
19. bitree *elements[M];
20. int top;
21.} seqstack; //定义一个储存树类型地址的栈,方便遍历的时候追踪到树的地址。
22.
23.bitree *root;//定义一个树根
24.seqstack s;//定义栈
25.
26.void setnull() { //初始化栈
27. s.top = 0;
28.}
29.
30.void push(bitree *temp) { //入栈操作
31. s.elements[s.top++] = temp;
32.}
33.
34.bitree *pop() { //取栈顶并出栈顶
35. return s.elements[--s.top];
36.}
37.
38.int empty() { //判断空栈
39. return s.top == 0;
40.}
41.
42.void preorder(bitree *t) { //前序遍历的非递归算法
43. bitree *temp = t;//定义一个树节点,用它来遍历
44.
45. while (temp != NULL || s.top != 0) {
46. while (temp != NULL) { //先遍历左孩子,并输出。
47. printf("%4d", temp->number);
48. push(temp);
49. temp = temp->lchild;
50. }
51.
52. if (s.top != 0) { //当左孩子遍历完后,取栈顶,找右孩子。此时循环还没有结束,再遍历它的左孩子,直至孩子全部遍历结束。
53. temp = pop();
54. temp = temp->rchild;
55. }
56. }
57.
58. printf("\n");
59.}
60.
61.int max(int a, int b) {
62. if (a > b)
63. return a;
64. else
65. return b;
66.}
67.
68.int GetHeight(struct tree *tree) {//确定树的深度
69. if (!tree)
70. return -1;
71. else
72. return (max(GetHeight(tree->lchild), GetHeight(tree->rchild))) + 1;
73.}
74.
75.
76.bitree *Findleves(struct tree *tree, int number) {
77.
78. bitree *p;
79.
80.
81.
82. if (tree->number == number) {
83. p = tree;
84. }
85.
86. if (tree->lchild != NULL)
87. p = Findleves(tree->lchild, number);
88.
89. if (tree->rchild != NULL)
90. p = Findleves(tree->rchild, number);
91.
92. if (p != NULL)
93. return p;
94. else
95. return 0;
96.}
97.
98.void printfleves(struct tree *tree, int n) { //凹顺序
99. int i;
100.
101. if (tree == NULL)
102. return;
103.
104. printfleves(tree->rchild, n + 1); //访问根节点
105.
106. for (i = 0; i < n; i++)
107. printf("\t\t");
108.
109. if (n > 0) {
110. printf("---");
111. printf("%d\n", tree->number);
112. }
113.
114. printfleves(tree->lchild, n + 1);
115.}
116.
117.void deepqianprintfleves(struct tree *tree, int deep) { //前序遍历
118. if (deep == 0)
119. printf("(叶子节点)");
120. else
121. printf("(非叶子节点)");
122.
123. printf("%d\n", tree->number);
124.
125. if (tree->lchild != NULL)
126. deepqianprintfleves(tree->lchild, deep - 1);
127.
128. if (tree->rchild != NULL)
129. deepqianprintfleves(tree->rchild, deep - 1);
130.}
131.
132.void qianprintfleves(struct tree *tree) { //前序遍历
133.
134. printf("%d\t", tree->number);
135.
136. if (tree->lchild != NULL)
137. qianprintfleves(tree->lchild);
138.
139. if (tree->rchild != NULL)
140. qianprintfleves(tree->rchild);
141.}
142.
143.void zhongprintfleves(struct tree *tree) {//中顺序
144. if (tree->lchild != NULL)
145. zhongprintfleves(tree->lchild);
146.
147. printf("%d\t", tree->number);
148.
149. if (tree->rchild != NULL)
150. zhongprintfleves(tree->rchild);
151.}
152.
153.void houprintfleves(struct tree *tree) {//后顺序
154. if (tree->lchild != NULL)
155. houprintfleves(tree->lchild);
156.
157. if (tree->rchild != NULL)
158. houprintfleves(tree->rchild);
159.
160. printf("%d\t", tree->number);
161.}
162.
163.void LevelOrderTraversal (struct tree *root) { //二叉树的层次遍历
164. queue *front = (queue *)malloc(sizeof(queue)), *rear = (queue *)malloc(sizeof(queue));
165. front->data = root;
166. front->next = rear;
167.
168. while (front != rear) {
169.
170. printf("%d\t", front->data->number); //输出队首结点
171.
172.
173. if (front->data->lchild) { //把Pop掉的结点的左子结点加入队列
174. rear->data = front->data->lchild;
175. rear->next = (queue *)malloc(sizeof(queue));
176. rear = rear->next;
177. }
178.
179. if (front->data->rchild) { //把Pop掉的结点的右子结点加入队列
180. rear->data = front->data->rchild;
181. rear->next = (queue *)malloc(sizeof(queue));
182. rear = rear->next;
183. }
184.
185. front = front->next;
186. }
187.}
188.
189.void CreatTree( struct tree *tree, FILE *fp1, int deep) {//对树叶递归建立
190. int number;
191. fscanf(fp1, "%d", &number);
192. tree->number = number;
193.
194. if (feof(fp1) || deep == 0) {
195. tree->lchild = NULL;
196.
197. } else if (!feof(fp1)) {
198. tree->lchild = (struct tree *)malloc(sizeof(struct tree));
199. CreatTree(tree->lchild, fp1, deep - 1);
200. }
201.
202. if (feof(fp1) || deep == 0) {
203. tree->rchild = NULL;
204.
205. } else if (!feof(fp1)) {
206. tree->rchild = (struct tree *)malloc(sizeof(struct tree));
207. CreatTree(tree->rchild, fp1, deep - 1);
208. }
209.}
210.
211.void CreatTreeTop(struct tree *p) {//建立树根部,打开文件
212. FILE *fp1;
213. int deep;
214. printf("\t\t\t\t请输入树的最大深度\n");
215. scanf("%d", &deep);
216.
217. if ((fp1 = fopen("a.txt", "r") ) != NULL) {
218. printf("FILE can open\n");
219. }
220.
221. if (feof(fp1)) {
222. p->lchild = NULL;
223. p->rchild = NULL;
224. } else if (!feof(fp1)) {
225. CreatTree(p, fp1, deep);
226. }
227.
228. fclose(fp1);
229.}
230.
231.int main() {
232. int i, a, number;
233. struct tree *p;
234. p = (struct tree *)malloc(sizeof(struct tree));
235. CreatTreeTop(p);
236. printf("\t\t\t\t1、前序遍历打印\t\t2、中序遍历打印\t\t3、后序遍历打印\n");
237. printf("\t\t\t\t4、寻找数字地址\t\t5、层次遍历打印\t\t6、凹型遍历打印\n");
238. printf("\t\t\t\t7、获得树的深度\t\t8、非递归前序遍历\t9、打印叶子或非叶节点\n");
239.
240. while (1) {
241. scanf("%d", &i);
242.
243. switch (i) {
244. case 1:
245. qianprintfleves(p);
246. break;
247.
248. case 2:
249. zhongprintfleves(p);
250. break;
251.
252. case 3:
253. houprintfleves(p);
254. break;
255.
256. case 4:
257. struct tree *leaf;
258. printf("请输入你要查找的number\n");
259. scanf("%d", &number);
260. leaf = Findleves(p, number);
261. printf("%d\n", leaf);
262. break;
263.
264. case 5:
265. LevelOrderTraversal (p);
266. break;
267.
268. case 6:
269. printfleves(p, 0); //凹遍历
270. break;
271.
272. case 7:
273. a = GetHeight(p);
274. printf("深度是%d\n", a);
275. break;
276.
277. case 8:
278. preorder(p);
279. break;
280.
281. case 9:
282. a = GetHeight(p);
283. deepqianprintfleves(p, a);
284. break;
285. }
286.
287. printf("\n--------------------------------------------\n");
288. }
289.}