数据结构与算法⑩(第四章_上)树和二叉树和堆的概念及结构

目录

1.树概念及结构

1.1树的概念

1.2树的相关概念

1.3树的表示

1.4树在实际中的运用

2.二叉树概念及结构

2.1二叉树的概念

2.2 满二叉树

2.3完全二叉树

2.4二叉树的性质

2.4.1二叉树性质相关选择题:

2.5二叉树的顺序存储:

2.6二叉树的链式存储:

3.堆的概念及结构

3.1小堆:

3.2大堆:

3.3堆的作用

4.树的笔试选择题

答案及解析

本篇完。(附下篇链接)


1.树概念及结构

1.1树的概念

树是一种非线性的数据结构,它是由 n(n >= 0)个有限节点组成的一个具有层次关系的集合。

那么为什么叫 "树" 呢? (节点也可以称结点,建议称结点,和结构体对上)

之所以把它成为 "树",是因为它很像现实生活中的树。只是它是倒过来的,根朝上叶子朝下。

① 树有一个特殊的结点,成为根结点,根节点不存在前驱结点。

② 除根结点外,其余结点被分成 M(M>0) 个互不相交的集合 T1、T2、……、Tm,

其中每一个集合 Ti(1 <= i <= m) 又是一颗结构于树类似的字数。

每颗子树的结点有且只有一个前驱,可以有0个或多个后继。

③ 因此,树是递归定义的。因为任何树都会被分成根和子树。


1.2树的相关概念

节点的度一个节点含有的子树的个数称为该节点的度; 如上图:A的为6

叶节点或终端节点:度为0的节点称为叶节点; 如上图:B、C、H、I...等节点为叶节点

非终端节点或分支节点度不为0的节点; 如上图:D、E、F、G...等节点为分支节点

双亲节点或父节点若一个节点含有子节点,则这个节点称为其子节点的父节点;

如上图:A是B的父节点

孩子节点或子节点一个节点含有的子树的根节点称为该节点的子节点

如上图:B是A的孩子节点

兄弟节点:具有相同父节点的节点互称为兄弟节点; 如上图:B、C是兄弟节点

树的度:一棵树中,最大的节点的度称为树的度; 如上图:树的度为6

节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推;

( 有些书上规定根节点的层数为0,这样空树就是-1了,所以若没有特殊说明默认规定根节点的层数为 1)

树的高度或深度:树中节点的最大层次; 如上图:树的高度为4

节点的祖先:从根到该节点所经分支上的所有节点;如上图:A是所有节点的祖先

子孙:以某节点为根的子树中任一节点都称为该节点的子孙。如上图:所有节点都是A的子孙

森林:由m(m>0)棵互不相交的多颗树的集合称为森林;(数据结构中的学习并查集本质就是

一个森林)


注意:树型结构中,子树之间不能有交集,否则就不是树形结构。


1.3树的表示

以前学单链表时只有一个指针,双链表两个指针,但是树有多少个指针是不确定的,

因为树没有规定一个节点最多有多少个孩子。那该如何定义结构呢?


法一:假设说明了树的度为N,才能勉强用


struct TreeNode 
{
    int data;
    struct TreeNode* sub[N]; // 指针数组
};

问题点:

① 可能会存在不少的空间浪费。

② 万一没有限定树的度为多少呢?


法二:vector顺序表(C++中这里可以用 vector,但是C里没有)


// 假设我们定义了一个顺序表
typedef int STLDataType;  //顺序表的数据类型
typedef struct TreeNode* SLDataType; // 顺序表中存节点的指针
struct TreeNode //SeqList
{
    STLDataType data;
    SeqList s;  // s为SLDataType* array;
};

即使你没有告诉我度是多少,我有多少个孩子我就存多少个孩子,所以这里不需要关心度的问题。

但是这里 s 的结构相对复杂,s 里面有一个类型为SLDataType* 的数组,

这个数组已经是二级指针了,SLDataType 展开后又是一个 struct TreeNode* 。


法三:双亲表示法


struct TreeNode 
{
    int parenti;
    int data;
};

[ A -1] [ B0 ] [ C0 ] [ D0 ] ...... [ H 3 ]

每一个元素中存的是结构体 struct TreeNode arr[10]

每个元素内只存自己的值和父亲的下标

(A没有父亲是-1,B的父亲下标是0…… H的父亲是D下标为3),可以通过一个值找到自己父亲。


上列的方式各有优缺点,那么有没有最优的方法?

当然有,它就是左孩子右兄弟表示法


typedef int DataType;
struct Node 
{
    struct Node* leftChind1;   // 永远指向第一个孩子
    struct Node* rightBrother;  // 指向孩子右边的兄弟
    DataType _data;
};

解读:无论你有多少个孩子,它都只存两个指针。一个指针永远指向第一个孩子,

另一个指针指向孩子右边的兄弟(亲兄弟)。这个树的度无论为多少,也不需要用顺序表存,

但是你任何一个节点有多少个孩子都能给你表示出来,通过第一个孩子把所有孩子都找出来。

不复杂也没有浪费,只用两个指针就把链接关系都表示出来了,这就是巨佬的智慧。


1.4树在实际中的运用

文件系统的目录树结构、网络拓扑,最短路径问题,搜索引擎、思维导图等


2.二叉树概念及结构

2.1二叉树的概念

定义:二叉树既然叫二叉树,顾名思义即度最大为2的树称为二叉树。

它的度可以为 1 也可以为 0,但是度最大为 2 。

一颗二叉树是节点的一个有限集合,该集合:

① 由一个根节点加上两颗被称为左子树和右子树的二叉树组成

② 或者为空

观察上图我们可以得出如下结论:

① 二叉树不存在度大于 2 的节点,换言之二叉树最多也只能有两个孩子。

② 二叉树的子树有左右之分,分别为左孩子和右孩子。次序不可颠倒,因此二叉树是有序树。

注意:对于任意的二叉树都是由以下几种情况复合而成的:


2.2 满二叉树

定义:一个二叉树,如果每一层的节点数都达到了最大值(均为2),

则这个二叉树就可以被称作为 "满二叉树" 。

换言之,如果一个二叉树的层数为h ,且节点总数是 2^h-1,则他就是一个满二叉树。

层数为N的计算公式:


2.3完全二叉树

定义:对于深度为h的,有 n个结点的二叉树,当且仅当其每一个结点都与深度为h的满二叉树中编号从 1 至 n的结点一一对应时称之为完全二叉树。

前h-1层是满的,最后一层不满,但是最后一层从左到右是连续的。

完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。

所以,满二叉树是一种特殊的完全二叉树(每一层节点均为2)。

常识:

① 完全二叉树中,度为 1 的最多只有 1 个。

② 高度为 h的完全二叉树节点范围是

(如果不是满二叉树,最小个数就是倒数第一层(满二叉树)的高度算出的节点数+1(至少有一个),是满二叉树最大个数就是2^h - 1)


2.4二叉树的性质

四点规则:

① 若规定根节点的层数为 1 ,则一颗非空二叉树的第i层上最多有2^(i-1)个节点。

② 若规定根节点的层数为1,则深度为h的二叉树的最大结点数是2^h- 1.

(此时为满二叉树)(等比数列公式)

③ 任何一棵二叉树, 如果叶结点(度为0)个数为 n0, 度为2的分支结点个数为 n2,则有n0=n2+1

(从只有一个结点(空树度也是0),逐个增加,就可以找到规律)

④ 若规定根节点的层数为1,具有N个结点的满二叉树的深度h=log(N+1)(log以2为底)。


2.4.1二叉树性质相关选择题:

1. 某二叉树共有 399 个结点,其中有 199 个度为 2 的结点,则该二叉树中的叶子结点数为( )

A. 不存在这样的二叉树

B. 200

C. 198

D. 199

2.在具有 2n 个结点的完全二叉树中,叶子结点个数为( )

A. n

B. n+1

C. n-1

D. n/2

3.一棵完全二叉树的节点数位为531个,那么这棵树的高度为( )

A. 11

B. 10

C. 8

D. 12

4. 一个具有767个节点的完全二叉树,其叶子节点个数为()

A. 383

B. 384

C. 385

D. 386


答案解析:

1. n0=n2+1

2.假设叶子节点(度为0)有X个 则度为2的节点有x-1个,完全二叉树中度为1的节点为0个或1个

所以X+(X-1)+(0或1)=2n,所以叶子结点x个数为n

3.具有N个结点的满二叉树的深度h=log(N+1)(log以2为底)。

高度为 h的完全二叉树节点范围是

2的9次方= 512,2的10次方 - 1 = 1023 在范围内

4.同2 假设叶子节点有X个 则度为0的节点有x-1个,完全二叉树中度为1的节点为0个或1个

X+(X-1)+(0或1)=767 , x=383

1.B

2.A

3.B

4.A


2.5二叉树的顺序存储:

顺序结构存储就是使用数组来存储,一般使用数组只适合表示完全二叉树,因为不是完全二叉树会有空间的浪费。而现实中使用中只有堆才会使用数组来存储,关于堆后面的章节会专门讲解。

二叉树顺序存储在物理上是一个数组,在逻辑上是一颗二叉树。

完全二叉树的顺序存储中

若父亲下标是i,则左孩子下标是2 * i + 1 右孩子下标是2 * i + 2

若孩子下标是i,则父亲下标是( i - 1)/2

像上面左图中C下标为2,左孩子F下标就为2 * 2 + 1=5,右孩子G下标为2 * 2 + 2=6,

D下标为3,E下标为4 则父亲B下标为(3 -1)/ 2 = 1 或者(4 -1)/ 2 = 1。

2.6二叉树的链式存储:

二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。

通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,

左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址 。

链式结构又分为二叉链和三叉链,当前我们学习中一般都是二叉链,

后面学到高阶数据结构如红黑树等会用到三叉链。


// 二叉链
struct BinaryTreeNode
{
    struct BinTreeNode* pLeft;   // 指向当前节点左孩子
    struct BinTreeNode* pRight; // 指向当前节点右孩子
    BTDataType _data; // 当前节点值域
}
// 三叉链
struct BinaryTreeNode
{
    struct BinTreeNode* pParent; // 指向当前节点的双亲
    struct BinTreeNode* pLeft;   // 指向当前节点左孩子
    struct BinTreeNode* pRight; // 指向当前节点右孩子
    BTDataType _data; // 当前节点值域
}

3.堆的概念及结构

【百度百科】堆(Heap)是计算机科学中一类特殊的数据结构的统称。
堆通常是一个可以被看做 一棵完全二叉树的数组对象

完全二叉树的性质就是堆的性质,堆是完全二叉树的顺序结构存储。

① 堆总是一棵完全二叉树。

② 堆中的某个节点的值总是不大于或不小于其父节点的值。

堆的物理结构是数组,逻辑结构则是二叉树。

堆有多种,其中典型的是:大堆 和 小堆。

3.1小堆:

任意一个节点的两个子节点都比自己的值大或相等,也就是根最小,整个二叉树从上到下递增。

父亲位,比孩子位,要小


3.2大堆:

任意一个节点的两个子节点都比自己的值小或相等,也就是根最大,整个二叉树从上到下递减。

父亲位,比孩子位,要大


常考选择题:

解析:

题目只说明是堆,大堆小堆都可以。

一个个分析后发现除了A都不是

A差不多是这样:

                100

        60                 70

50                 32         65


3.3堆的作用

① 八大排序算法之一:堆排序

解决TopK问题,在N个数中找出最大的前K个或找出最小的K个......


4.树的笔试选择题

1.在用树表示的目录结构中,从根目录到任何数据文件,有( )通道

A.唯一一条

B.二条

C.三条

D.不一定


2.在一颗度为3的树中,度为3的结点有2个,度为2的结点有1个,度为1的结点有2个,则叶子结点有( )个

A.4

B.5

C.6

D.7


3.一颗拥有1000个结点的树度为4,则它的最小深度是( )

A.5

B.6

C.7

D.8


4.下列关于二叉树的叙述错误的是( )

A.二叉树指的是深度为 2 的树

B.一个 n 个结点的二叉树将拥有 n-1 条边

C.一颗深度为 h 的满二叉树拥有 2^h-1 个结点(根结点深度为1)

D.二叉树有二叉链和三叉链两种表示方式


5.一颗完全二叉树有1001个结点,其叶子结点的个数是( )

A.251

B.500

C.501

D.不能确定


6.在一颗完全二叉树中,某一个结点没有其左孩子,则该结点一定( )

A.是根结点

B.是叶结点

C.是分支结点

D.在倒数第二层


7.设一棵二叉树中有3个叶子结点,有8个度为1的结点,则该二叉树中总的结点数为( )个

A.11

B.12

C.13

D.14


8.下列关于树的叙述正确的是( )

A.树中可以有环

B.树的度是指所有结点中度最小的结点的度

C.树的深度指的是结点数最多的那一层的深度

D.树的根结点是所有结点的祖先结点


9.有n个元素的完全二叉树的深度是( )

A.nlogn

B.nlogn+1

C.logn

D.logn+1


答案及解析

(可以开两个网页对着题目看)

1.答案:A

解析:

树的特点是不相交,所以不可能有多个路径同时到达一个点。

2.答案:C

解析:

设度为i的节点个数为ni, 该树总共有n个节点,则n=n0+n1+n2+n3.

有n个节点的树的总边数为n-1条.

根据度的定义,总边数与度之间的关系为:n-1=0*n0+1*n1+2*n2+3*n3.

联立两个方程求解,可以得到n0 = n2 + 2n3 + 1, n0=6

3.答案:B

解析:

如果这棵树每一层都是满的,则它的深度最小,假设它为一个四叉树,高度为h,则这个数的节点个数为(4^h - 1) / 3,当h = 5, 最大节点数为341, 当h = 6, 最大节点数为1365,所以最小深度应该为6。

4.答案:A

解析:

A错误: 二叉树指最大孩子个数为2,即树的度为二的树。深度描述的为树的层数。

B正确: 对于任意的树都满足:边的条数比节点个数少1,因为每个节点都有双亲,但是根节点没有

C正确: 正确,参加二叉树性质

D正确: 二叉链一般指孩子表示法,三叉连指孩子双亲表示法,这两种方式是二叉树最常见的表示方式,虽然还有孩子兄弟表示法,该中表示方式本质也是二叉链

5.答案:C

解析:

该题需要用到二叉树性质:在任意二叉树中,度为0的节点都比度为2的节点多1个,即 n0 = n2 + 1

另外,在完全二叉树中,如果节点总个数为奇数,则没有度为1的节点,如果节点总个数为偶数,只有一个度为1的节点

因此:n0 + n1 + n2 = 1001 节点总数为奇数,没有度为1的节点

n0 + 0 + n2 = 2*n0-1 = 1001 n0 = 501

6.答案:B

解析:

完全二叉树中如果一个节点没有左孩子,则一定没有右孩子,必定为一个叶子节点,最后一层一定为叶子节点,但是倒数第二层也可能存在叶子节点。

7.答案:C

解析:

设Ni表示度为i的节点个数,则节点总数 N = N0 + N1 + N2

节点个数于节点边的关系: N个节点的树有N-1个边

边与度的关系:N - 1 = N1 + 2 * N2

故:N0 + N1 + N2 - 1 = N1 + 2 * N2

因此,得:N0 = N2 + 1

回到原题,N0 = 3,N1 = 8,可得N2 = 2。

因此答案是 3 + 8 + 2 = 13。

8.答案:D

解析:

A: 树中的节点不能相交

B: 树的度为所有节点中度最大的节点的度

C: 树的深度为根节点到叶子节点的最大深度

9.答案:D

解析:

参考完全二叉树的特性,高度h = log(n)向上取整 注意:底数是2


本篇完。(附下篇链接)

下一篇我们用代码讲讲堆的分步构建

讲完堆的分步构建,讲讲堆排序,然后配合OJ题解决TopK问题

穿越回来贴个链接:

数据结构与算法⑪(第四章_中)堆的分步构建_GR C的博客-CSDN博客

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
数据结构与算法是计算机科学的基础和核心领域之一,第ba章介绍了数据结构的相关内容。 本章主要包括以下几个方面的内容: 1. 线性结构:线性结构是指数据元素之间存在一对一的关系,包括线性表、栈和队列。线性表是最基本的数据结构之一,它分为顺序表和链表两种形式。顺序表使用数组实现,插入和删除操作相对低效。链表使用指针实现,插入和删除操作较为灵活。 2. 结构结构是一种层次结构,由节点和边组成。常见的结构二叉树、二叉搜索和平衡二叉树等。二叉树中每个节点最多有两个子节点,二叉搜索中左子节点的值小于根节点,右子节点的值大于根节点,查找效率较高。平衡二叉树是一种保持左右子高度差不大于1的二叉搜索。 3. 图结构:图结构是由节点和边组成的非线性结构。图分为有向图和无向图。图的表示方法有邻接矩阵和邻接表两种。深度优先搜索和广度优先搜索是图的常用遍历方法,可用于寻找路径、连通分量等问题。 4. 排序算法:排序算法是对一组无序数据进行按照某个规则进行有序排列的算法。第ba章介绍了常见的排序算法,包括冒泡排序、插入排序、选择排序、归并排序、快速排序等。每种排序算法的时间复杂度和空间复杂度不同,选择合适的排序算法可以提高性能。 5. 查找算法:查找算法是在一组数据中搜索某个特定元素的算法。第ba章介绍了顺序查找、二分查找和哈希查找等常见的查找算法。二分查找是在有序数组中应用最广泛的查找算法,通过不断缩小查找范围来快速定位目标值。 通过学习这些内容,我们可以了解不同数据结构的特点和应用场景,以及常见的排序和查找算法。掌握好这些知识,对于解决实际问题和提高程序效率都有很大帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GR鲸鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值