数据结构与算法C语言

五、树与二叉树

1树的定义

树是n(n>=0)个结点的有限集。当n = 0时,称为空树。在任意一棵非空树中应满足:

1.有且仅有一个特定的称为根的结点。
2.当n>1时,其余节点可分为m(m>0)个互不相交的有限集T1,T2,…,Tm,其中每个集合本身又是一棵树,并且称为根的子树。

显然,树的定义是递归的,即在树的定义中又用到了自身,树是一种递归的数据结构。树作为一种逻辑结构,同时也是一种分层结构,具有以下两个特点:

1.树的根结点没有前驱,除根结点外的所有结点有且只有一个前驱。
2.树中所有结点可以有零个或多个后继。
因此n个结点的树中有n-1条边。
 

1.1树的基本术语

 考虑结点K。根A到结点K的唯一路径上的任意结点,称为结点K的祖先。如结点B是结点K的祖先,而结点K是结点B的子孙。路径上最接近结点K的结点E称为K的双亲,而K为结点E的孩子。根A是树中唯一没有双亲的结点。有相同双亲的结点称为兄弟,如结点K和结点L有相同的双亲E,即K和L为兄弟。
树中一个结点的孩子个数称为该结点的度,树中结点的最大度数称为树的度。如结点B的度为2,结点D的度为3,树的度为3。
度大于0的结点称为分支结点(又称非终端结点);度为0(没有子女结点)的结点称为叶子结点(又称终端结点)。在分支结点中,每个结点的分支数就是该结点的度。
结点的深度、高度和层次。
结点的层次从树根开始定义,根结点为第1层,它的子结点为第2层,以此类推。双亲在同一层的结点互为堂兄弟,图中结点G与E,F,H,I,J互为堂兄弟。
结点的深度是从根结点开始自顶向下逐层累加的。
结点的高度是从叶结点开始自底向上逐层累加的。
树的高度(或深度)是树中结点的最大层数。图中树的高度为4。
有序树和无序树。树中结点的各子树从左到右是有次序的,不能互换,称该树为有序树,否则称为无序树。假设图为有序树,若将子结点位置互换,则变成一棵不同的树。
路径和路径长度。树中两个结点之间的路径是由这两个结点之间所经过的结点序列构成的,而路径长度是路径上所经过的边的个数。
注意:由于树中的分支是有向的,即从双亲指向孩子,所以树中的路径是从上向下的,同一双亲的两个孩子之间不存在路径。
森林。森林是m (m≥0)棵互不相交的树的集合。森林的概念与树的概念十分相近,因为只要把树的根结点删去就成了森林。反之,只要给m棵独立的树加上一个结点,并把这m棵树作为该结点的子树,则森林就变成了树。

1.2树的性质

树是一种无环连通图,具有以下性质:

1. 一个树由若干个节点和边组成,每个节点之间通过边连接,且每个节点最多只能有一个父节点。
2. 树中有一个特殊的节点,称为根节点,没有父节点的节点被称为叶子节点。
3. 除了根节点外,每个节点都有唯一的父节点。
4. 从根节点到任意一个节点都存在唯一的路径。
5. 任意两个节点之间的路径是唯一的,即树中不存在重复的边。
6. 一个树中的任意两个节点之间的路径长度是确定的,即路径上的边数是固定的。
7. 一个树可以有多个子树,每个子树由一个根节点和其所有子节点组成。
8. 一个树的高度是指从根节点到叶子节点的最长路径的长度。
9. 一个树的深度是指从根节点到任意节点的路径的长度。
10. 一个树的节点数等于所有子树的节点数之和加一。

1.3树的存储结构

1、双亲表示法

我们假设以一组连续空间存储树的结点,同时在每个结点中,附设一个指示器指示其双亲结点到链表中的位置。也就是说,每个结点除了知道自已是谁以外,还知道它的双亲在哪里。

其中data是数据域,存储结点的数据信息。而parent是指针域,存储该结点的双亲在数组中的下标。

2、孩子表示法

具体办法是,把每个结点的孩子结点排列起来,以单链表作存储结构,则n个结点有n个孩子链表,如果是叶子结点则此单链表为空。然后n个头指针又组成-一个线性表,采用顺序存储结构,存放进一个一维数组中,如图所示。

为此,设计两种结点结构,一个是孩子链表的孩子结点。

其中child是数据域,用来存储某个结点在表头数组中的下标。next 是指针域,用来存储指向某结点的下一个孩子结点的指针。

另一个是表头数组的表头结点。

其中data是数据域,存储某结点的数据信息。firstchild 是头指针域,存储该结点的孩子链表的头指针。

3、孩子兄弟表示法


刚才我们分别从双亲的角度和从孩子的角度研究树的存储结构,如果我们从树结点的兄弟的角度又会如何呢?当然,对于树这样的层级结构来说,只研究结点的兄弟是不行的,我们观察后发现,任意一棵树, 它的结点的第一个孩子如果存在就是唯一的,它的右兄弟如果存在也是唯一的。 因此,我们设置两个指针,分别指向该结点的第一个孩子和此结点的右兄弟。
结点的结构如下:

其中data是数据域,firstchild 为指针域,存储该结点的第一个孩子结点的存储地址,rightsib 是指针域,存储该结点的右兄弟结点的存储地址。
这种表示法,给查找某个结点的某个孩子带来了方便。

于是通过这种结构,我们就把原来的树变成了这个样子

 这不就是个二叉树么?
没错,其实这个表示法的最大好处就是它把一棵复杂的树变成了一棵二叉树
 

1.4树的基本运算

寻找插入删除遍历

先根遍历

1.访问根节点

2.按照从左到右的顺序先根遍历每一棵子树

后根遍历

1.按照从左到右的顺序后根遍历每一棵子树

2.访问根节点

层次遍历

从根结点开始按从上到下、从左到右的次序访问树的每一个结点

2.二叉树

2.1二叉树的定义

二叉树是另一种树形结构,其特点是每个结点至多只有两棵子树( 即二叉树中不存在度大于2的结点),并且二叉树的子树有左右之分,其次序不能任意颠倒。
与树相似,二叉树也以递归的形式定义。二叉树是n (n≥0) 个结点的有限集合:

1.或者为空二叉树,即n=0。
2.或者由一个根结点和两个互不相交的被称为根的左子树和右子树组成。左子树和右子树又分别是一棵二叉树。
二叉树是有序树,若将其左、右子树颠倒,则成为另一棵不同的二叉树。即使树中结点只有一棵子树,也要区分它是左子树还是右子树。二叉树的5种基本形态如图所示。

2.1.1特殊二叉树 
1斜树


所有的结点都只有左子树的二叉树叫左斜树。所有结点都是只有右子树的二叉树叫右斜树。这两者统称为斜树。

2满二叉树


一棵高度为h ,且含有2^ h − 1 个结点的二叉树称为满二叉树,即树中的每层都含有最多的结点。满二叉树的叶子结点都集中在二叉树的最下一层,并且除叶子结点之外的每个结点度数均为2 。可以对满二叉树按层序编号:约定编号从根结点(根结点编号为1 )起,自上而下,自左向右。这样,每个结点对应一个编号,对于编号为i的结点,若有双亲,则其双亲为i / 2 ,若有左孩子,则左孩子为2 i;若有右孩子,则右孩子为2 i + 1 。

 3完全二叉树

高度为h 、有n 个结点的二叉树,当且仅当其每个结点都与高度为h 的满二叉树中编号为1~n的结点一一对应时,称为完全二叉树,如图所示。其特点如下:

 1.若i ≤ n / 2 i≤n/2i≤n/2, 则结点i 为分支结点,否则为叶子结点。
2.叶子结点只可能在层次最大的两层上出现。对于最大层次中的叶子结点,都依次排列在该层最左边的位置上。
3.若有度为1的结点,则只可能有一个,且该结点只有左孩子而无右孩子(重要特征)。
4.按层序编号后,一旦出现某结点(编号为i)为叶子结点或只有左孩子,则编号大于i ii的结点均为叶子结点。
5.若n 为奇数,则每个分支结点都有左孩子和右孩子;若n 为偶数,则编号最大的分支结点(编号为n / 2 )只有左孩子,没有右孩子,其余分支结点左、右孩子都有。

4二叉排序树

左子树上所有结点的关键字均小于根结点的关键字;右子树上的所有结点的关键字均大于根结点的关键字;左子树和右子树又各是一棵二叉排序树。

5平衡二叉树

树上任一结点的左子树和右子树的深度之差不超过1。

2.2二叉树的性质

非空二叉树上的叶子结点数等于双分支结点数加1;

2.3二叉树与树、森林之间的转换

2.3.1森林、树转化为二叉树
树转化为二叉树

将一棵树转换成二叉树的过程如下:
(1) 树中所有相邻兄弟之间加一条连线
(2) 对树中的每个结点只保留它与长子(即最左边的孩子结点)之间的连线,删除与其孩子之间的连线。
(3)以树的根结点为轴心,将整棵树顺时针转动 45,使之结构层次分明

森林转化为二叉树

若要转换为二叉树的森林由两棵或两棵以上的树构成,将这样的森林转换为二叉树的过程如下:
(1) 将森林中的每棵树转换成相应的二叉树
(2)第一棵二叉树不动,从第二棵二叉树开始,依次把后一棵二叉树的根结点作为前一棵二叉树的根结点的右孩子结点,当所有二叉树连在一起后,此时得到的二叉树就是由森林转换得到的二叉树。

2.3.2二叉树还原为树、森林
二叉树还原树

若一棵二叉树是由一棵树转换而来的,则该二叉树还原为树的过程如下:
(1)若某结点是其双亲的左孩子,则把该结点的右孩子、右孩子的右孩子等都与该结点的双亲结点用连线连起来。

(2) 删除原二叉树中所有双亲结点与右孩子结点之间的连线。

(3)整理由前面两步得到的树,即以根结点为轴心,逆时针转动 45,使之结构层次分明。

实际上,二叉树的还原就是将二叉树中的左分支保持不变,将二叉树中的右分支还原成兄弟关系。

二叉树还原森林

若一棵二叉树是由 m 棵树构成的森林转换而来的,该二叉树的根结点一定有 m -1个右下孩子,该二叉树还原为森林的过程如下:
(1)抹掉二叉树根结点右链上的所有结点之间的“双亲一右孩子”关系,将其分成若干个以右链上的结点为根结点的二叉树,设这些二叉树为 bt1、bt2、···、btm

(2) 分别将二叉树 bt1;  bt2,、···、btm 各自还原成一棵树。

2.4二叉树的存储结构

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

初遇在光年之外

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

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

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

打赏作者

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

抵扣说明:

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

余额充值