• 二叉树和二叉树排序


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

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

    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

  • 相关阅读:
    多线程之旅:避免死锁——简单的锁分级(锁排序)
    和我一起来学iOS(三)UIView及其子类(上)
    谈谈.NET中常见的内存泄露问题——GC、委托事件和弱引用
    和我一起来学iOS(二)iOS中的一些约定、模式与三种回调机制
    多线程之旅六——异步编程模式,自己实现IAsyncResult
    详解JavaScript中的函数与闭包
    和我一起来学iOS(一)ObjectC的语法
    浅谈SQL SERVER中的物理联接算法
    多线程之旅之三——Windows内核对象同步机制
    深入 聚集索引与非聚集索引(一)
  • 原文地址:https://www.cnblogs.com/cafe-cat/p/10339377.html
Copyright © 2020-2023  润新知