数据结构-树

导读:本篇文章讲解 数据结构-树,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

是由若干个有限结点组成的一个具有层次关系的集合,每棵树有且仅有一个根,比如在图中,最上面的结点就是树的根结点。例子里的/、etc、usr、lib等等都是这棵树上的结点,其中/是树的根结点。
在这里插入图片描述

二叉树

二叉树的性质

  • 二叉树的第 i 层最多有

    2

    i

    1

    2^{i−1}

    2i1 个结点。

  • 由定义可知,二叉树的每个结点最多有两个孩子结点,那么第 i 层最多的结点数等于第 i−1 层最多结点数的 2 倍。而第 1 层最多只有 1 个结点,所以我们可以知道第 i 层最多有

    2

    i

    1

    2 ^ {i – 1}

    2i1 个结点。

  • 深度为 k 的二叉树最多有

    2

    k

    1

    2 ^ k – 1

    2k1 个结点。由上一个性质,我们可以知道二叉树每层最多的结点个数,从第 1 层到第 k 层把最多结点数累加起来,我们就可以得到深度为 k 的二叉树最多有

    2

    k

    1

    2 ^ k – 1

    2k1 个结点。

  • 任意一棵二叉树上,其叶子结点个数

    n

    0

    n_0

    n0 比度为 2 的结点数

    n

    2

    n_2

    n2 多1。

  • 我们记树上结点总个数为 n,度为 1 的结点个数为

    n

    1

    n_1

    n1,则有 n =

    n

    0

    n_0

    n0 +

    n

    1

    n_1

    n1 + $n_2 n=n 。

  • 另外我们可以发现一棵二叉树一共有 n−1 条边,度为 2 的结点可以延伸出 2 条边,度为 1 的结点可以延伸出 1 条边,叶子结点没有边延伸出来,所以又有 n – 1=

    n

    1

    n_1

    n1 + 2 ×

    n

    2

    n_2

    n2

  • 结合以上两个式子,我们可以得到

    n

    0

    n_0

    n0 =

    n

    2

    n_2

    n2 + 1。

满二叉树和完全二叉树

第一个是 满二叉树 ,如果一棵树深度为 k 而且有

2

k

1

2 ^ k – 1

2k1 个结点,那么我们称该二叉树为满二叉树,也就是说在此深度上,不能再添加结点了。
第二个是 完全二叉树 ,如果一棵树深度为 k,从第 1 层到第 k – 1 层该树是满二叉树,第 k 层的结点都集中在左边,那么我们称该二叉树为完全二叉树。完全二叉树因其结构的特殊性具有很高的效率,经常被用在算法的优化里。

二叉树的广义表表示形式

我们可以用广义表来表示二叉树,形式为 a(b,c),表示根节点 a 的左孩子节点为 b,右孩子节点为 c,中间用一个逗号隔开。如果左右孩子节点不为空,则用以上形式来替换;如果节点为空,则不填任何字符。以下是几种常见的格式:

  • a:表示根节点为 a,左右孩子节点均为空;
  • a(b):表示根节点为 a,左孩子节点为 b,右孩子节点为空;
  • a(,c):表示根节点为 a,左孩子节点为空,右孩子节点为 c;
  • a(b,c):表示根节点为 a,左孩子节点为 b,右孩子节点为 c。
    如 7(4(3,6),15(,55)) 可以表示以下这棵二叉树:
    在这里插入图片描述

如何将广义表创建成二叉树

将广义表创建成二叉树,可以借助栈来实现,利用栈先进后出的特点,先将根节点压入栈中,如果左孩子节点不为空,则将其作为栈顶节点(即其父亲节点)的左孩子节点,并压入栈中,递归左子树,处理完之后左孩子节点出栈;如果右孩子不为空,则将其作为栈顶节点(即其父亲节点)的右孩子节点,并压入栈中,递归右子树,处理完之后右孩子节点出栈。
在转换过程中,我们可以这么理解,左括号表示进入二叉树的下一层,右括号表示返回上一层,逗号表示从左子树转到右子树。
用广义表创建二叉树的伪代码如下:

设置一个标记变量 k,初始为 -1;
设置一个标记节点 p;
循环遍历存储广义表的字符串 str:
    如果 str[i] 是左括号:
        则设置 k 为 0;
        把 p 压入栈中。
    否则如果 str[i] 是逗号:
        则设置 k 为 1。
    否则如果 str[i] 是右括号:
        则栈顶元素出栈。
    否则如果 str[i] 是一个字母,用节点 temp 来存储:
        如果 k 为 -1:
            则把 temp 作为根节点并压入栈中。
        如果 k 为 0:
            如果此时栈顶节点是 p,则先出栈;
            然后将 temp 作为栈顶节点的左孩子;
            再把 temp 压入栈中。
        如果 k 为 1:
            栈顶元素出栈;
            将 temp 作为栈顶节点的右孩子;
            再把 temp 压入栈中。

如何输出二叉树的广义表的形式

输出二叉树的广义表形式,有点类似于二叉树的先序遍历。先输出根节点,如果左孩子不为空则递归输出左子树,如果右孩子不为空则递归输出右子树,在输出过程中,根据节点是否为空,在合适的地方输出左右括号以及逗号。
输出二叉树的广义表形式的伪代码如下:

输出节点存储的值;
如果左孩子不为空:
    输出 "(";
    递归输出左子树;
    如果右孩子为空:
        输出 ")"。
如果右孩子不为空:
    如果左孩子为空:
        输出 "("。
    输出 “,”;
    递归输出右子树;
    输出 ")"

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/77026.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!