二叉树和二叉树排序

很长时间没有看过数据结构了,二叉树都淡忘了,赶紧复习一下。

二叉树是每个结点最多有两个子树的树结构。下面就定义一下如下:

1 struct tree
2 {
3     int data;
4     struct tree *child_l;
5     struct tree *child_r;
6 };

关于二叉树,有多种遍历方式,前序,中序和后序,前中后代表了根节点的顺序,就是先根,中根,后根。

遍历分为递归遍历和非递归遍历。

递归遍历的代码非常简单。一下就是以前序为例子,进行前序遍历:

1 void read_tree(struct tree *t) {
2     printf("%d\n",t->data);
3     if (t->child_l != NULL)
4         read_tree(t->child_l);
5     if (t->child_r != NULL)
6         read_tree(t->child_r);
7 }

非递归需要借助栈的数据结构,那么首先建立一个栈:

1 struct stack {
2     struct tree* stack_value[10];
3     int top;
4 };

并且初始化一个栈:

1 #define NOMAL_COUNT 1
2 
3 struct stack* init_stack() {
4     struct stack *s = (struct stack *) calloc(NOMAL_COUNT, sizeof(struct stack));
5     s->top = -1;
6     return s;
7 }

然后是入栈和出栈:

 1 void stack_push(struct stack *s, struct tree *t) {
 2     s->top++;
 3     s->stack_value[s->top] = t;
 4 }
 5 
 6 struct tree* stack_pop(struct stack *s) {
 7     struct tree *t = s->stack_value[s->top];
 8     s->top--;
 9     return t;
10 }

接下来就是非递归遍历,非递归就是根完了一直向左,左边完全完了再访问右边:

 1 void read_tree2(struct tree *t) {
 2     struct tree * temp = t;
 3     struct stack *s = init_stack();
 4     
 5     while (temp != NULL || s->top != -1) {
 6         while (temp != NULL) {
 7             printf("%d\n", temp->data);
 8             stack_push(s, temp);
 9             temp = temp->child_l;
10         }
11         if (s->top != -1) {
12             temp = stack_pop(s); 
13             temp = temp->child_r;
14         }
15     }
16 }

初始化一下这个树:

 1 struct tree *t = (struct tree *) calloc(NOMAL_COUNT, sizeof(struct tree));
 2 struct tree *temp;
 3 t->data = 1;
 4 t->child_l = (struct tree *) calloc(NOMAL_COUNT, sizeof(struct tree));
 5 temp = t->child_l;
 6 temp->data = 2;
 7 temp->child_l = (struct tree *) calloc(NOMAL_COUNT, sizeof(struct tree));
 8 temp->child_l->data = 4;
 9 temp->child_r = (struct tree *) calloc(NOMAL_COUNT, sizeof(struct tree));
10 temp->child_r->data = 5;
11 t->child_r = (struct tree *) calloc(NOMAL_COUNT, sizeof(struct tree));
12 t->child_r->data = 3;

然后开始遍历就好啦,得到:1,2,4,5,3.

接下来是二叉树排序:

可以将小的放在左孩子上,大的放在右孩子上:

 1 void add_tree(struct tree *t, int number) {
 2     if (t->data > number) {
 3         if (t->child_l != NULL) {
 4             add_tree(t->child_l, number);
 5         } else {
 6             t->child_l = (struct tree *) calloc(NOMAL_COUNT, sizeof(struct tree));
 7             t->child_l->data = number;
 8         }
 9     } else {
10         if (t->child_r != NULL) {
11             add_tree(t->child_r, number);
12         } else {
13             t->child_r = (struct tree *) calloc(NOMAL_COUNT, sizeof(struct tree));
14             t->child_r->data = number;
15         }
16     }
17 }

然后就可以中序遍历二叉树,输出排序结果了:

1 // 中序遍历二叉树
2 void read_tree(struct tree *t) {
3     if (t->child_l != NULL)
4         read_tree(t->child_l);
5     printf("%d\n",t->data);
6     if (t->child_r != NULL)
7         read_tree(t->child_r);
8 }

我们来测试一下:

 1 int main(int argc, char const *argv[])
 2 {
 3     int numbers[] = {8, 7, 1, 4, 3, 5, 9, 19, 13, 11, 15, 20, 16, 2, 6};
 4     struct tree *t = (struct tree *) calloc(NOMAL_COUNT, sizeof(struct tree));
 5     t->data = numbers[0];
 6     for (int i = 1; i < 15; i++) {
 7         add_tree(t, numbers[i]);
 8     }
 9     read_tree(t);
10     return 0;
11 }

输出结果:

1
2
3
4
5
6
7
8
9
11
13
15
16
19
20

 

posted @ 2019-01-30 18:36  小马甲奶糖  阅读(490)  评论(0编辑  收藏  举报