比较重要的内容
树形结构是一类重要的非线性数据结构,树中结点之间具有明确的层次关系,并且结点之间有分支。树形结构在客观世界中大量存在,如行政组织机构和人类社会的家谱等都可用树形结构形象地表示。
逻辑上,树的特点:
(1)任何非空树中有且仅有一个结点没有前驱结点,这个结点就是树的根结点。
(2)除根结点之外,其余所有结点有且仅有一个直接前驱结点。
(3)包括根结点在内,每个结点可以有多个直接后继结点。
(4)树形结构是一种具有递归特征的数据结构。
(5)树形结构中的数据元素之间存在的关系通常是一对多,或者多对一的关系。
另一种是:广义表表示法
(A(B(E,(F(J,K))),C(G),D(H,I)))
(1)结点的度,可以理解为宽度:结点所拥有的子树的个数。
(2)树的度:树中结点度的最大值。
(3)叶子(终端结点):度为0的结点。
(4)分支结点(非终端结点):度不为0的结点。除根结点之外的分支结点统称为内部结点。根结点又称为开始结点。
(5)路径:若树中存在一个结点序列k1,k2,…,ki,使得ki是ki+1的双亲(1≤i
(6)结点的层:设根结点的层数为1,其余结点的层数等于双亲结点的层数加1。如B的层数是2,N的层数是4。
(7)树的高度(或深度):树中所有结点层数的最大值。图所示的树的高度为4。
(8)有序树和无序树:将树中每个结点的各子树看成是从左到右有次序的(即不能互换),则称该树为有序树;否则称为无序树。
(9)森林:是m(m≥0)棵互不相交的树的集合。树和森林的概念相近,删去一棵树的根,就得到一个森林;反之,加上一个结点作树根,森林就变为一棵树。
性质一:非空树中的结点总数等于树中所有结点的度之和加1。除根结点之上没有线外,其他结点上面都有线,所以是+1.
性质二:度为k的非空树的第i层最多有ki -1个结点(i≥1)。这个的理解就是每个结点的度都为k,所以才有“最多”一说。
性质三:深度为h的k叉树最多有 k h − 1 k − 1 \frac{\mathrm{k}^{\mathrm{h}}-1}{\mathrm{k}-1} k−1kh−1 个结点。这点可由性质二推导出来,只不过是i取值范围[0,h-1],而不是一个具体的值了。也就是k0+k1+…+kh-1这个表达式的计算要讲些技巧了,最好是结合一棵满二叉树来解或满三叉树来解。规律就是:假设存在h层,那么前面所有结点的个数为,h层满度kh-1除以满度-1.
软考时,总结的一些树的知识,顺便也复习下。数据结构与算法基础
一棵深度为k且有2k-1个结点的二又树称为满二叉树。
(1) 每一层上的结点数都达到最大值。即对给定的高度,它是具有最多结点数的二叉树。满二叉树的结点总数一定是奇数。
(2) 满二叉树中不存在度数为1的结点,每个分支结点均有两棵高度相同的子树,且叶结点都在最下一层上
若一棵二叉树至多只有最下面的两层上结点的度数可以小于2,并且最下一层上的结点都集中在该层最左边的若干位置上,则此二叉树称为完全二叉树。
(1) 满二叉树是完全二叉树,完全二叉树不一定是满二叉树。
(2) 在满二叉树的最下一层上,从最右边开始连续删去若干结点后得到的二叉树仍然是一棵完全二叉树。
(3) 在完全二叉树中,若某个结点没有左孩子,则它一定没有右孩子,即该结点必是叶结点。
具有n个结点的完全二叉树的深度为
如果将一棵有n个结点的完全二叉树按层从1开始编号,则对任一编号为i (l≤i≤n)的结点X有:
若i=1,则结点X是根;若i> l,则X的双亲的编号为 i/2下取整。
若2i>n,则结点X无左孩子(且无右孩子);否则,X的左孩子编号为2i。
若2i+1>n,则结点X无右孩子;否则,X的右孩子的编号为2i+1。
如下图所示:看图理解:完全二叉树,右孩子结点为2i+1,左孩子为2i
对应的性质5,存储就要从0开始编号。
对任一编号为i (0≤i
若2i+1
显然是按完全二叉树存储,用@补齐缺的结点。
① 对完全二叉树而言,顺序存储结构既简单又节省存储空间。
② 一般的二叉树采用顺序存储结构时,虽然简单,但易造成存储空间的浪费。最坏的情况下,一个深度为k且只有k个结点的右单支树需要2k-1个结点的存储空间(相当于满二叉树)。
③在对顺序存储的二叉树做插入和删除结点操作时,要大量移动结点。
lchild | data | rchild |
---|
说明:
①数据域data,用以存放元素值。
②指针域lchild和rchild,分别指向该结点的左孩子和右孩子。没有左孩子时lchild=NULL, 没有右孩子时rchild=NULL
问题:为什么二叉链会有n+1个指针域为空??脑补出,只有三个结点的完全二叉树的情形。
当二叉树有n个结点时,其二叉链表上共有2n个指针域,其中只有n-1个指针域用于存放其左、右孩子的指针(n个结点的二叉树一共有n-1个分支),剩下的n+l个指针域为空。
typedef struct node {
DataType data;
Struct node *lchild, *rchild;//左右孩子指针
} BinTNode;
//结点类型
typedef BinTNode *BinTree;
//BinTree为指向BinTNode类型结点的指针类型
llchild | data | parent | rchild |
---|
问题:什么是叉呢?其实就是指针域。三叉,就是有三个指针域,还是要脑补出只有三个结点的情形。其中根结点,有2个指向孩子结点,而孩子结点的父结点分别指向根,所以有2个指针域指向双亲,剩下的5个结点指针域为空。
三叉链表结构与二叉链表结构的区别是它的结点多了一个指向双亲的指针域。当二叉树有n个结点时,其三叉链表上共有3n个指针域,其中只有n-1个指针域用于存放其左、右孩子的指针,有n-1个指向双亲,剩下的n+2个指针域为空。