考研数据结构学习笔记.树的常考性质

树的常考性质

树作为重要的数据结构,通常在操作系统,算法等领域起着重要的作用。其特殊性质需要我们了解并且运用,在考研中他们通常会以选择题的形式出现,我们需要熟练掌握并且能够准确地计算。

一.结点数 = 总度数 + 1

这个性质是显而易见的,总度数就是这个树中每个结点的度数和。由于树的特殊结构以及度数的定义,我们可以发现第n-1层的结点度数之和就是第n层的所有结点数量,如此循环往复,我们就能知道从第1层到第n层的结点度数和实际上就是除了根节点之外的所有结点的数量。虽然根节点之上并没有其他结点,但是这不影响我们知道根节点只有一个,因此我们可以得到重要推论就是:结点数 = 总度数 + 1

二.度为m的树和m叉树的区别

度为m的树m叉树
任意结点度数最多等于m任意节点度数最多等于m
至少有一个结点的度等于m允许所有结点的度都小于m
不允许为空树可以为空树

实际上度为m的树和m叉树是两个不同的概念,其中度为m的树是对于某一个已经具体存在的树的描述,而m叉树则是一种特殊的亚结构,是一种数据结构的定义。度为m的树要求它已经是棵树了而且度必须为m,这就要求它必须存在,所以不能为空树,同时至少有一个结点的度为m。而m叉树是一种抽象的结构,是一种对树的约束规则的具体表现形式,它可以为空树,但是每个结点的度数必须小于等于m。简单来讲,度为m的树强调这是一棵已经存在的,度为m的树;m叉树在强调这一种树在结构上必须严格遵守任一结点度都小于m这一规定

三.度为m的树,第i层最多m^{^{i-1}}个结点

这里强调了一点:最多,因此当度为m的树中结点最多时它是一棵满树,同时由于其每一个结点最多度为m,此时它从结构上看就是一颗满m叉树,因此这时它的第i层就是第i-1层的m倍,所以这导致其每层结点个数呈1,m,m^{2} ......m^{^{i-1}}。(第一层是m的0次方,但是是第一层,所以和层数对应是要减一,从而有m^{^{i-1}})

四.高度为h的m叉树,至多有\frac{m^{h}-1}{m-1}个结点

这里再次强调了至多,同上,它从结构上看就是一棵满m叉树。求结点数时这里使用到了等比数列的前n项和公式,我们从第三个性质很容易看出来满m叉树的每一层结点数其实就是一个公比为m,首项为1的等比数列。因此这里直接使用等比数列求和公式求出这个结果。

等比数列求和公式:a+aq+aq^{^{2}}+......+aq^{h-1} = \frac{a(1-q^{n})}{1-q}。直接带入公式得到结果。

五.高度为h的m叉树至少有h个结点;高度为h,度为m的树至少有h+m-1个结点

这里其实可以作为一个理解m叉树和度为m的树之间区别的契机。高度为h的m叉树不见得度为m,只是它强调每个结点的度最大为m,因此当它高度为m时允许每个结点度为h,这样串成一串下来,这时它的结点是最少的,此时除了叶子结点外每一个结点的度为1。

度为m的树则又多加了一个限制:至少有一个结点度为m,这时我们可以在高度为h的m叉树的基础上再多增加几个结点使其度数增加到m,由于高度是h已经限定死了,我们不能在叶子结点上增加,这样会导致h增加,因此我们只能再额外增加m-1个,使得某一个非叶子结点的度从1增加到m。

六.具有n个结点的m叉树的最小高度为\left \lceil log_{m}(n(m-1)+1) \right \rceil

这个性质是最难的,也是很常考的性质,这个性质通过计算得来。

当具有限定的n个结点时,m叉树为完全m叉树时高度是最少的。简单来说就是我们如果将构造这棵树的过程理解为把游离的结点一个一个放到树上,我们将按照每一层的每一个结点的顺序一个一个放,并且满足每一个结点的度都达到m,一个结点不放完,不允许放下一个。

这时我们假设n个结点放完后它的高度为h,我们使用性质四:高度为h的m叉树,至多有\frac{m^{h}-1}{m-1}个结点。所以我们可以发现h和n的关系就出来了:\frac{m^{h-1}-1}{m-1} < n ≤\frac{m^{h}-1}{m-1}

这是因为n个结点不见得组成了一个满m叉树,因此它的结点数可能比最大值小,因为\frac{m^{h}-1}{m-1}是高度为h时的最大值。但是n一定比\frac{m^{h-1}-1}{m-1}小,因为他是树只有h-1层时的最大值。所以它的值介于二者之间,我们通过这个关系便算出了h的取值范围,从而能得到它的最小高度。

1.                  \frac{m^{h-1}-1}{m-1} < n ≤\frac{m^{h}-1}{m-1}

2.                  m^{h-1}-1 < n(m-1) ≤m^{h}-1

3.                  m^{h-1} < n(m-1)+1 ≤m^{h}

4.                  h-1 < log_{m}(n(m-1)+1) ≤ h

这样一来我们就知道了h和h-1和n的关系,因为 log_{m}(n(m-1)+1)处于h-1和h之间,因此它是一个小数,当然高度不能是小数,然而它是由n通过数学运算得到的结果,其本身拥有浓烈的数学性:这里的h代表的其实是满m叉树算出来的高度h,h-1也是满m叉树情况下得到的结果,而仅给的结点数n不见得可以组成相应的满m叉树,所以通过n算出来的结果实际上代表了完全二叉树通过相应公署推导出的数学结果,简单来说,它的高度到h了,但是不是一个满二叉树,差这么几个结点,而这种情况在数学上表现为高度是一个大于h-1小于h的小数。然而只要第h层有一个结点,这个树也应该是h层,因此我们对它向上取整,得到了\left \lceil log_{m}(n(m-1)+1) \right \rceil

  • 16
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
5.1 数的逻辑结构 5.1.1 1、的定义 在中常常将数据元素称为结点 (1)有且仅有一个特定的称为根的结点; (2)当n>1时,除根结点之外的其余结点被分成m(m>0)个互不相交的有限集合T1,T2,•••Tm,其中每个集合又是一棵,并称为这个节点的子。 2、的基本术语: 结点的度、的度 叶子节点、分支结点 孩子节点、分支结点、兄弟节点 路径、路径长度 祖先、子孙 结点的层数、的深度(高度) 层序编号 有序、无序 森林 5.1.2 的抽象数据类型定义 5.1.3的遍历操作 1、前序遍历 的前序遍历操作定义为: 若为空,则空操作返回;否则 (1)访问根结点 (2)按照从左向右的顺序前序遍历根结点的每一棵子。 2、中序遍历 的中序遍历操作定义为: 若为空,则空操作返回;否则 (1)按照从左向右的顺序后序遍历根结点的每一棵子; (2)访问根结点。 3、层序遍历 的层序遍历也称作的广泛遍历,其操作定义为的第一层开始,自上而下逐层遍历,在同一层中,按从左向右的顺序对结点逐个访问。 5.2的存储结构 5.2.1 双亲表示法 由的定义可知,中每个结点都有且仅有一个双亲结点。所以利用这一特性,可以用一维数组来存储各个结点,数组中一个元素对应一个结点,数组元素包括中结点的数据信息以及该结点的双亲在数组中的下标。 其中: Data为数据域,存储中结点的数据信息; Parent为指针即游标,存储该结点的双亲在数组中的小标。 5.2.2孩子表示法 1、多重链表表示法 (1)指针域的个数等于该结点的度。 (2)指针域的个数等于的度。 2、孩子链表表示法 把孩子看成一个线性表,且以单链表存储,称为该结点的孩子链表。则n个结点有n个孩子链表。 孩子节点有两类:孩子节点、表头结点。 5.2.3 双亲孩子表示法 即将双亲表示法和孩子链表表示法相结合的存储方法。仍将各结点的孩子分别组成单链表,同时用一维数组顺序存储中的各结点,数组元素除了包括结点的数据信息和该结点的孩子链表的头指针之外,还增设一个域存储该结点的双亲在数组的下标。 5.2.4孩子兄弟表示法 又称二链表表示法,其方法是链表中每个结点除数据域外,还设置了两个指针分别指向该结点的第一个孩子和右兄弟链表的结构: Firstchild data rightsib 指针域,存储第一个孩子结点的存储地址 数据域,存储该结点的数据信息 指针域,存储该结点右兄弟结点的存储地址 5.3二的逻辑结构 最简单的结构,特别适合计算机处理,而且任何数都可以简单的转换为二。(重点内容) 5.3.1二的定义 二是n(n>=0)个结点的有限集合,该集合或者为空集,或者有一个根节点和两棵互不相交的、分别称为根节点的左子和右子的二组成。 二具有五种基本形态: 1、空二; 2、只有一个根结点; 3、根结点只有左子; 4、根结点只有右子; 5、根结点既有左子又有右子 特殊二: 1、斜; 2、满二; 3、完全二; 5.3.2二的基本性质 性质5-1 二的第i层上最多有2^(i-1)个结点(i>=1)。 性质5-2 在一棵深度为k的二中,最多有2^k-1个结点,最少有k个结点。 性质5-3 在一棵二中,如果叶子结点的个数为n0,度为2的结点个数为n2,则n0=n2+1. 性质5-4 具有n个结点的完全二的深度为【log2^n】+1。 性质5-5 对一棵具有n个结点的完全二中的结点从一开始按层序编号,则对于任意的编号为i(1<=i<=n)的结点,有: (1)如果i>1,则结点i的双亲的编号为【i/2】;否则结点i是根结点,无双亲。 (2)如果2i<=n,则 结点i的左孩子的编号为2i;否则结点i无左孩子。 (3)如果2i+1<=n,则结点i的右孩子的编号为2i+1,否则结点i无右孩子。 5.3.3 二的抽象数据类型定义 同类似,在不同的应用中,二的基本操作不尽相同。 5.3.4 二的遍历操作 二的遍历是指从根节点出发,按照某种次序访问二是所有结点,使得每个结点被访问一次且仅被访问一次。由于二中每个结点都可能有两个子,因此需要寻找一条合适的搜索路径。 1、前序遍历 前序遍历二操作定义为: 若为空,则空操作返回;否则 (1)访问根结点 (2)前序遍历根结点的左子 (3)前序遍历根结点的右子 2、中序遍历 中序遍历二操作定义为: 若为空,则空操作返回;否则 (1)中序遍历根结点的左子 (2)访问根结点 (3)中序遍历根结点的右子 3、后序遍历 后序遍历根结点的左子 后序遍历根结点的右子 访问根结点 4、层序遍历 二的层序遍历是指从二的第一层开始,从上之下逐层遍历,在同一层中,按从左到右的顺序对结点逐个访问。 5.4 二存储结构及实现 5.4.1 顺序存储结构 具体步骤: (1)将二按完全二编号。 (2)将二中的结点一编号顺序存储到一维数组中。 5.4.2 二链表 基本思想: 令二的每个结点对应一个链表结点,链表结点除了存放于二结点有关的数据信息外,还要设置指示左右孩子的指针。 5.4.3 三链表 在二链表存储方式下,从某个结点出发可以直接访问它的孩子结点,但要找到它的双亲结点,则需要从根节点开始搜索,最坏的情况下,需要遍历整个二链表。此时采用三链表储存二。 其中,data,lchild,rchild三个域的含义同二,parent域为指向该结点的双亲结点指针。 5.4.4 线索链表 按照某种遍历次序对二进行遍历,可以把二中所有结点排成一个线性序列。在集体应用中,有时需要访问二中的结点在某种遍历序列中前驱和后继,此时,在存储结构中应该保存结点在某种遍历序列中的前驱和后继信息。 前驱和后继结点的指针称为线索,加上线索的二称为线索二,加上线索的二链表称为线索链表。 5.5 二遍历的非递归算法 5.5.1 前序遍历非递归算法 关键:在前序遍历过某个左子后,如何找到该结点的右子的根指针。 一般的前序遍历执行过程中,设要遍历二的根指针为bt,可能出现两种情况: (1)若bt!=NULL,则表明当前二不为空,此时,应输入根结点bt的值并将bt保存到栈中,准备继续遍历bt的左子。 (2)若bt=NULL,则表明以bt为根指针的二遍历完毕,并且bt是栈顶指针所指结点的左子,若栈不空,则应根据栈顶指针所指结点找到待遍历右子的根指针并赋予bt,以继续遍历下去;若栈空,则表明整个二遍历完毕。 5.5.2 中序遍历非递归算法 此算法只是需要将前序遍历的非递归算法中输出的语句cout<<bt->data移到bt=s[top--]之后即可。 5.5.3 后序遍历非递归算法 后序遍历的不同在于:结点要出入两次栈,出两次栈,这种情况的含义和处理方法为: (1)第一次出栈:只遍历晚左子,右子尚未遍历,则该结点不出栈,利用栈顶结点找到它的右子,准备遍历它的右子。 (2)第二次出栈:遍历完右子,该结点出栈,并访问它。 设根指针为bt,则可能有以下两种情况: (1)若bt!=NULL,则bt及标志flag入栈,遍历其左子。 (2)若bt=NULL,此时栈空,则整个遍历结束;若栈不空,则表明栈顶结点的左子或右子已遍历结束。若栈顶点的标志flag=1,则表明栈结点的左子已遍历完毕,将flag修改为2,修改为2,并遍历栈定点的右子;若栈顶结点的标志flag=2,则表明栈结点的右子也遍历完毕,输出栈顶结点。 5.6 、森林与二的转换 1.转换为二 将一棵转换为二的方法为: (1)加线——中所有相邻的兄弟结点之间加一条线; (2)去线——对中的每个节点,只保留它与第一个孩子结点之间的连线,删去它与其他孩子结点之间的连线。 (3)层次调节——以根结点为轴心,将顺时针转动一定角度,使之层次分明。 2.森林转换成二 (1)将森林中的每一棵二转化成二; (2)从第二课二开始,依次把后一棵二的根结点作为一棵二根节点的右孩子,当所有二连起来后,此时所得到的二就是由森林转换得到的二。 3、二转换为或森林 (1)加线——若某个结点x是其双亲y的左孩子,则把结点x的右孩子、右孩子的右孩子、……,都与结点y用线连起来; (2)去线——删去原二中所有的双亲结点与右孩子结点的连线; (3)层次调整——整理由(1)、(2)两步所得到的或森林,使之层次分明。 (4)森林的遍历 两种遍历方法;前序遍历后续遍历。 5.7 应用举例 5.7.1 二的应用举例——哈夫曼及哈夫曼编码 1、哈夫曼也称最优二,在实际中有着广泛的应用。 叶子节点的权值 是对叶子结点赋予的一个有意义的数值量。 二的带权路径长度 设二具有n个带权值的叶子节点,从根节点到叶子节点的路径长度与相应的叶子节点权值的乘积之和叫做二的带权路径长度,记为: WPL=EWkLk 哈夫曼 给定一组具有确定权值的叶子结点,可以构造出不同的二,将其中带权值路径长度最小的二称为哈夫曼。 哈夫曼算法基本思想: (1)初始化:由给定的n个权值构造n棵只有一个根结点的二,从而得到一个二集合。 (2)选取与合并:在F中选取根结点的权值最小的两棵二分别作为左、右子构造一棵新的二,这棵新的二的根结点的权值为其左右子根结点的权值之和。 (3)删除与加入:在F中删除作为左、右子的两棵二,并将新建的二加入到F中。 (4)重复(2)(3)两步的操作,当集合F只剩下一棵二时这棵二便是哈夫曼。 2、哈夫曼编码 在进行程序设计时,通常给每一个字符记一个单独的代码来表示一组字符,我们称之为编码。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值