二叉树通常有顺序存储结构和链式存储结构
(1)先忽略虚线部分,只看实线,进行后序遍历,得dbca前驱后继关系
(2)考虑每个结点,当左孩子为空时,指向前驱;右孩子为空时指向后继。(用虚线)
结点d,无左右孩子,则指向前驱null,后继b
结点b, 无左孩子,则指向前驱d
结点c,无左右孩子,则指向前驱b,后继a
结点a,, 有左右孩子。
设森林F中有三棵树,第一、第二、第三棵树的结点个数分别为M1,M2和M3。则与森林F对应的二叉树根结点的右子树上的结点个数是:
根据森林转换为二叉树的法则,二叉树的根结点通常是第一棵树的结点,二叉树的左子树是由第一棵树删去根后所得所有子树构成的,二叉树的右子树是由其它树(第二,第三棵树)构成的,故左子树结点个数是M1-1,右子树上的结点个数是M2+M
、逻辑结构
集合——数据元素间除“同属于一个集合”外、无其他关系
线性结构——一对一、如线性表、栈、队列。 ——数组和广义表是线性表的推广
树形结构——一对多(非线性)、如树
树形结构实例: 树形结构中、节点间的关系是前驱唯一而后继不唯一、
组织结构 即节点之间是一对多的关系
家谱
目录树
树的定义与基本术语
树:是n(n>=0)个节点的有限集合T
当n=0时称为空树
当n>0时、该集合满足以下条件
1、其中必有一个称为根(root)的特定节点、它没有直接前驱、但有零个或多个直接后继。
2、其余n-1个节点可以划分成m(m>=0)个互不相交的有限集T1、T2、T3......Tn、其中Ti又是一棵树、称为根root的子树。每棵子树的根节点有且仅有一个直接前驱、但有零个或多个直接后继。
表示方法:1、树形表示
表示方法:2、文氏图表示(嵌套集合表示法)
表示方法:3、凹入表示
用位置的缩进表示其层次、比如书的目录、程序的锯齿形结构。
表示方法:4、广义表形式(嵌套括号表示)
(a ( b ( d, e ( i, j ),f), c ( g, h ) ) )
根:即结点(没有前驱)除根结点外的分支节点统称为内部结点。
1、结点:包括一个数据元素及若干指向其他结点的分支信息。
2、结点的度:一个结点的子树个数(即分支的个数)。
3、叶子结点:度为0的结点、即无后继的结点、也称终端节点。
4、分支结点:度不为零的结点、也称非终端结点。
5、节点的层次:从根到该结点的层数(根结点为第一层)。
6、结点的层序编号:将树中的结点按从上到下、从左到右的次序排成一个线性序列、依次给他们编以连续的自然数。
7、树的度:树中所有结点的度的最大值。
8、树的高度(深度):树中所有结点的层次的最大值。
9、有序树:结点各子树从左至右有序、不能互换(左为第一)。
10、森林:指m(m>=0)棵不相交的树的集合(例如删除A后的子树个数)、反之、给森林增加一个统一的根结点、森林就变成一棵树。
同构:对两棵树,通过对结点适当地重命名,可以使两棵树完全相等(结点对应相等,对应结点的相关关系也相等),则称这两棵树同构。
11、孩子结点:一个结点的直接后继。
12、双亲结点:一个节点的直接前驱。
13、兄弟结点:同一双亲结点的孩子结点之间的互称。
14、堂兄弟:即双亲位于同一层的结点(但并非同一双亲)。
15、祖先结点:即从根到该结点所经分支的所有结点。
16、子孙结点:一个结点的直接后继和间接后继称为该结点的子孙结点、即该结点下层子树中的任一结点。
二叉树的定义
二叉树(Binary Tree)是n (n≥O)个结点所构成的集合,它或为空树(n =0);或为非空树,对于非空树T:
(1)有且仅有一个称之为根的结点;
(2)除根结点以外的其余结点分为两个互不相交的子集T1和T2,分别称为T的左子树和右子树,且T1和T,本身又都是二叉树。
特点、
1、每个结点的度都不大于2。
2、每个结点的孩子结点次序不能任意颠倒(有序树)。
二叉树与树(普通树、多叉树)的区别:
1、树中结点的最大度数没有限制,而二叉树结点的最大度数为2;
2、树的结点无左右之分,而二叉树的结点有左右之分;
3、二叉树和树都属于树形结构;
4、所有树都能转化为唯一对应的二叉树;
二叉树的存储结构及算法较为简单,规律性最强,适合计算机处理。
形态:5种
基本操作:
二叉树的性质
1、在二叉树的第 i 层上至多有2的 i-1 次方个结点。
2、深度为 k 的二叉树上至多含 2 的k次方-1个结点(k>=1)。
3、对任何一棵二叉树、若它含有n0个叶子结点、n2个度为2的结点、则必存在关系式:n0=n2+1。
两种特殊的二叉树
双亲结点求法、孩子结点求法
二叉树有顺序存储结构和链式存储结构
完全二叉树用顺序存储结构、不适合一般的二叉树、会造成空间浪费。
e
二叉树的遍历与线索化
按一定的规律对二叉树的每个结点进行访问、并且仅能访问一次。
遍历是任何类型均有的操作。
对二叉树进行遍历是为了得到线性结构:遍历目的
遍历操作就是将二叉树中结点按一定规律线性化的操作。
二叉树是非线性结构、每个节点有两个后继、如何遍历时、搜索路径访问节点且访问一次。
遍历的方法:(二叉树由三个基本单元组成:根结点(D)、左子树(L)、右子树(R))————是递归定义
DLR(先序):
LDR(中序):
LRD(后序):
6.4.1树的存储结构
1、双亲表示法 2、孩子表示法 3、孩子兄弟表示法
1、双亲表示法:
————用一组连续的空间来存储树中的结点、在保存每个结点的同时附设一个指示器来指示其双亲结点在表中的位置、其结点的结构如下:
双亲表示法的形式说明如下:一棵树可以定义为:
结点的定义 树的定义
双亲表示法的优点:
利用了树中每个结点(根结点除外)只有一个双亲结点的性质、使得查找某个结点的双亲结点非常容易。
双亲表示法的缺点:
在求某个结点的孩子时、需要遍历整个数组。时间复杂度 O(n)。
2、孩子表示法:
————通常把每个结点的孩子结点排列起来、构成一个单链表、称为孩子链表。n 个结点共有 n 个孩子链表(叶结点的孩子链表为空表)、而 n 个结点的数据和 n 个孩子链表的头指针又组成了一个顺序表。
孩子表示法的形式说明如下:
3、孩子兄弟表示法:(二叉链表表示法)
————链表中每个结点设有两个链域、分别指向该结点的第一个孩子结点和下一个兄弟(右兄弟)结点。
孩子兄弟表示法的类型定义如下:
优点:便于实现树的各种操作。
如上图:在内存中并没有这种关系、只是线性的。
树的孩子兄弟链表结构与二叉树的二叉链表结构在物理存储上是完全相同的、不同的是逻辑含义表示的不一样
6.4.2树、森林与二叉树的互相转换
1.树转换为二叉树
树中结点的各孩子的次序是无关紧要的、而二叉树中结点的左、右孩子是有区别的。我们约定树中每一个结点的孩子结点按从左到右的次序顺序编号、也就是说、把树作为有序树看待。如下图:
将一颗树转换为二叉树的方法:
1、树中所有相邻兄弟之间加一条连线。
2、对树中的每个结点、只保留其与第一个孩子结点之间的连线、删去其与其他孩子结点之间的连线。
3、以树的根结点为轴心、将整棵树顺时针旋转一定的角度、使之结构层次分明。
结论:
————从转换过程可看出:树中的任意一个结点都对应于二叉树中的一个结点。
————树中某结点的第一个孩子在二叉树中是相应结点的左孩子、树中某结点的右兄弟结点在二叉树中是相应结点的右孩子。
————也就是说、在二叉树中、左分支上的各结点在原来的树中是父子关系、而右分支上的各结点在原来的树中是兄弟关系。由于树的根结点没有兄弟、所以变换后的二叉树的根结点的右孩子必然为空。
2、森林转换为二叉树
方法为:
1.将森林中的每棵树转换成相应的二叉树。
2.第一棵树二叉树不动、从第二棵二叉树开始、依次把后一棵二叉树的根结点作为前一棵二叉树根结点的右孩子、当所有二叉树连在一起后、所得到的二叉树就是由森林转换得到的二叉树。
注意:森林和树都能转换为二叉树,两者的区别:
树转换而成的二叉树、其根结点必然无右孩子。
森林转换的二叉树、其根结点有右孩子。
3、二叉树还原为树或森林
1.若某结点是其双亲的左孩子、则把该结点的右孩子、右孩子的右孩子、......都与该结点的双亲结点用线连起来。
2.删掉原二叉树中所有双亲结点与右孩子结点的连线。
3.整理1、2两步所得到的树或森林使之结构层次分明。
ii 删掉原二叉树中所有双亲结点与右孩子结点的连线。
6.4.3树与森林的遍历
1、树的遍历(树的结构特点:树根、树的子树森林)树的遍历方法主要有以下两种:
1.先根遍历
若树非空、则遍历方法为:
————访问跟结点
————从左到右、依次先根遍历根结点的每一棵子树。
————如图、树的先根遍历序列为:ABECFHGD
2.后根遍历
若树非空、则遍历方法为:
————从左到右、依次后根遍历根结点的每一棵子树
————访问根结点
——————如图、树的后根遍历序列为:EB HFGCDA
树是没有中根遍历的 (树不分左右孩子)
2、森林的遍历(森林的结构特点:第一棵树、其余的树)
森林的遍历方法有三种:
1.先序遍历
若森林非空、则遍历方法为
————访问森林中第一棵树的根结点
————先序遍历第一棵树的根结点的子树森林
————先序遍历除去第一棵树之后剩余的树构成的森林
2.中序遍历
若森林非空、则遍历方法为
————中序遍历森林中第一棵树的根结点的子树森林
————访问第一棵树的根结点
————中序遍历除去第一棵树之后剩余的树构成的森林
BCDAFEHJIG 依次从左至右对森林中的每一棵树进行后根遍历
3.后序遍历
若森林非空、则遍历方法为
————后序遍历森林中第一棵树的根结点的子树森林
————后序遍历除去第一棵树之后剩余的树构成的森林
————访问第一棵树的根结点
D C B F J I H G E A