美文网首页
10-二叉树

10-二叉树

作者: 董泽平 | 来源:发表于2019-09-29 08:39 被阅读0次

二叉树

对于树这块,基础部分都好理解,我仅仅整理树的难点知识

我们先想一下,二叉树如何存储?顺序存储还是链式存储?
我们尝试用这两种方式都去尝试存储树

1.二叉树的顺序存储

tree1.jpg

我们用一个数组去顺序存储二叉树的节点。从数组下标1开始存储是为了方便计算孩子位置
每个节点的左孩子下标=2当前节点位置, 每个节点的右孩子下标=2当前节点位置+1
对比上图,很容易看出啦。

tree2.jpg

观察这个二叉树,数组很多空间没有被利用,所以顺序存储造成了巨大浪费。我们对比图1,发现,顺序存储适合存储完全二叉树。

2.二叉树的链式存储

tree3.jpg

上图就是二叉树的链式存储,我们发现很形象,也很具体的描述了二叉树。
这种存储适合非完全二叉树的存储。

3.二叉树的先序遍历

tree29.jpg

记住口号:中左右

先遍历自己,再左孩子,再右孩子。如图所示,此图的先序遍历结果是ABDECFG

//先序遍历代码
void pre_Order(struct Tree * t)
{
    if (t == NULL)
    {
        return;
    }
    printf("%c", t->data);
    pre_Order(t->left);
    pre_Order(t->right);
}

4。二叉树的中序遍历

tree29.jpg

记住口号:左中右

先遍历左孩子,再自己,再右孩子。如图所示,此图的先序遍历结果是DBEACGF

//中序遍历代码
void mid_Order(struct Tree * t)
{
    if (t == NULL)
    {
        return;
    }
    mid_Order(t->left);
    printf("%c", t->data);
    mid_Order(t->right);
}

5。二叉树的后序遍历

tree29.jpg

记住口号:左右中

先遍历左孩子,再右孩子,再自己。如图所示,此图的先序遍历结果是DEBGFCA

//后序遍历代码
void post_Order(struct Tree * t)
{
    if (t == NULL)
    {
        return;
    }
    mid_Order(t->left);
    mid_Order(t->right);
    printf("%c", t->data);
}

6.二叉树的层序遍历

层序遍历满足我们人的视角,就是一层一层的访问树的每个节点,但是二叉树的层序遍历需要借助一种数据结构完成,我们需要让一层一层从左到右逐个访问,那么肯定用队列再合适不过了,先进先出的特性可以很好的解决层序遍历问题。

层序遍历步骤:

  • 让根节点入队
  • 出队一个元素,并打印此元素,将此元素的左右孩子从左到右依次都入队列。
  • 循环执行步骤二,直到队列为空
tree29.jpg

模拟过程

  1. 让根节点入队
queue11.jpg

2.出队元素A,输出A,让它的孩子们逐个入队

queue12.jpg

3.出队元素B,输出B,让它的孩子逐个入队

queue13.jpg

4.出队元素C,输出C,让它的孩子们逐个入队

queue14.jpg

5.出队元素D,输出D,无孩子入队,出队元素E,输出E,无孩子入队。

queue15.jpg

6.出队元素F,输出F,让它孩子入队。

queue16.jpg

7.出队元素G,输出G,它无孩子,此时队列为空,遍历结束。

queue17.jpg

最终我们得到的中序遍历序列就是ABCDEFG

/************** 层序遍历 ********************/
void level_Order(struct Tree * t)
{
    struct Tree* q[MAX];//队列
    struct Tree* temp;
    int front, rear;
    front = rear = 0;
    if (t != NULL)
    {
        q[rear++] = t;
    }
    while (front != rear)
    {
        temp = q[front];
        front++;//模拟出队列
        printf("%c ", temp->data);
        if (temp->left != NULL)
        {
            q[rear++] = temp->left;
        }
        if (temp->right != NULL)
        {
            q[rear++] = temp->right;
        }
    }
}

7.二叉树求高度

tree4.jpg

观察上图,该树的高度可以递归求得。
...
树高度 = 1 + max(2分支高度,3分支高度);
2分枝高度 = 1 + max(0,4分枝高度);
3分枝高度 = 1 + max(0,5分枝高度);
...
我们可以发现递归公式:某个分枝高度 = 1 + max(左分支高度,右分枝高度);

int getHigh(struct Tree * t)
{
    if (t == NULL)
    {
        return 0;
    }
    return getHigh(t->left) > getHigh(t->right) ? getHigh(t->left) + 1 : getHigh(t->right) + 1;
}

8.二叉树的节点个数

tree4.jpg

继续观察图片,发现树节点个数还是可以用递归实现

...
树节点个数和 = 1 + 2分枝总个数 + 3分枝总个数
2分枝总个数 = 1 + 0 + 4分枝总个数
3分枝总个数 = 1 + 0 + 5分枝总个数
...

递归公式:节点个数 = 1 + 左分支节点数 +右分枝节点数

int getCount(struct Tree * t)
{
    if (t == NULL)
    {
        return 0;
    }
    else
    {
        return getCount(t->left) + getCount(t->right) + 1;
    }
}

相关文章

网友评论

      本文标题:10-二叉树

      本文链接:https://www.haomeiwen.com/subject/aoqnyctx.html