算法与数据结构---树

算法与数据结构—树

/设树结点的元素类型为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; //定义一个储存树类型地址的栈,方便遍历的时候追踪到树的地址。

主要操作算法思想或算法步骤:

  1. 通过文件读取方式,建立二叉树T(用递归方式创建)。
  2. 给定元素number,在二叉树中查找该元素x,若找到则返回该节点的指针。
  3. 凹入表示法打印该二叉树。
  4. 非递归方式先序遍历方式输出树T的结点;(用到栈)。
  5. 用中序或后序遍历方式输出树T的结点。
  6. 用层次遍历方式输出树T的结点;(用到队列)。
  7. 输出树T的深度。
  8. 利用前序遍历和深度得出树T的叶子结点或非叶子结点。

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.}  

程序运行结果//所有函数都运行一次

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值