性质1 二叉树第i层上的结点数目最多为2i-1(i≥1)。 证明:用数学归纳法证明: 归纳基础:i=1时,有2i-1=20=1。因为第1层上只有一个根结点,所以命题成立。 归纳假设:假设对所有的j(1≤j<i)命题成立,即第j层上至多有2j-1个结点,证明j=i时命题亦成立。 归纳步骤:根据归纳假设,第i-1层上至多有2i-2个结点。由于二叉树的每个结点至多有两个孩子,故第i层上的结点数至多是第i-1层上的最大结点数的2倍。即j=i时,该层上至多有2×2i-2=2i-1个结点,故命题成立。 性质2 深度为k的二叉树至多有2k-1个结点(k≥1)。 证明:在具有相同深度的二叉树中,仅当每一层都含有最大结点数时,其树中结点数最多。因此利用性质1可得,深度为k的二叉树的结点数至多为: 20+21+…+2k-1=2k-1 故命题正确。 性质3 在任意-棵二叉树中,若终端结点(叶子节点)的个数为n0,度为2的结点数为n2,则no=n2+1。 证明:因为二叉树中所有结点的度数均不大于2,所以结点总数(记为n)应等于0度结点数、1度结点(记为n1)和2度结点数之和: n=no+n1+n2 (式子1) 另一方面,1度结点有一个孩子,2度结点有两个孩子,故二叉树中孩子结点总数是: nl+2n2 树中只有根结点不是任何结点的孩子,故二叉树中的结点总数又可表示为: n=n1+2n2+1 (式子2) 由式子1和式子2得到: no=n2+1 满二叉树和完全二叉树是二叉树的两种特殊情形。 1、满二叉树(FullBinaryTree) 一棵深度为k且有2k-1个结点的二又树称为满二叉树。 满二叉树的特点: (1) 每一层上的结点数都达到最大值。即对给定的高度,它是具有最多结点数的二叉树。 (2) 满二叉树中不存在度数为1的结点,每个分支结点均有两棵高度相同的子树,且树叶都在最下一层上。 【例】图(a)是一个深度为4的满二叉树。 2、完全二叉树(Complete BinaryTree) 若一棵二叉树至多只有最下面的两层上结点的度数可以小于2,并且最下一层上的结点都集中在该层最左边的若干位置上,则此二叉树称为完全二叉树。 特点: (1) 满二叉树是完全二叉树,完全二叉树不一定是满二叉树。 (2) 在满二叉树的最下一层上,从最右边开始连续删去若干结点后得到的二叉树仍然是一棵完全二叉树。 (3) 在完全二叉树中,若某个结点没有左孩子,则它一定没有右孩子,即该结点必是叶结点。 【例】如图(c)中,结点F没有左孩子而有右孩子L,故它不是一棵完全二叉树。 【例】图(b)是一棵完全二叉树。 性质4 具有n个结点的完全二叉树的深度为 ![]() 证明:设所求完全二叉树的深度为k。由完全二叉树定义可得: 深度为k得完全二叉树的前k-1层是深度为k-1的满二叉树,一共有2k-1-1个结点。 由于完全二叉树深度为k,故第k层上还有若干个结点,因此该完全二叉树的结点个数: n>2k-1-1。 另一方面,由性质2可得: n≤2k-1, 即:2k-1-l<n≤2k-1 由此可推出:2k-1≤n<2k或者 2k-1<n+1≤2k,取对数后有: k-1≤lgn<k 或者 k-1< lg(n+1)≤k 又因k-1和k是相邻的两个整数,故有 ![]() ![]() 由此即得: ![]() 注意: ![]() 1.完全二叉树结点编号 (1) 编号办法 在一棵n个结点的完全二叉树中,从树根起,自上层到下层,每层从左至右,给所有结点编号,能得到一个反映整个二叉树结构的线性序列。 【例】如下图所示。 (2) 编号特点 完全二叉树中除最下面一层外,各层都充满了结点。每一层的结点个数恰好是上一层结点个数的2倍。从一个结点的编号就可推得其双亲,左、右孩子,兄弟等结点的编号。假设编号为i的结点是ki(1≤i≤n),则有: ①若i>1,则ki的双亲编号为 ![]() ②若2i≤n,则Ki的左孩子的编号是2i;否则,Ki无左孩子,即Ki必定是叶子。因此完全二叉树中编号 ![]() ③若2i+1≤n,则Ki的右孩子的编号是2i+1;否则,Ki无右孩子。 ④若i为奇数且不为1,则Ki的左兄弟的编号是i-1;否则,Ki无左兄弟。 ⑤若i为偶数且小于n,则Ki的右兄弟的编号是i+1;否则,Ki无右兄弟。 2.完全二叉树的顺序存储 将完全二叉树中所有结点按编号顺序依次存储在一个向量bt[0..n]中。 其中: bt[1..n]用来存储结点 bt[0]不用或用来存储结点数目。 【例】表6.1是图6.8所示的完全二叉树的顺序存储结构,bt[0]为结点数目,b[7]的双亲、左右孩子分别是bt[3]、bt[l4]和bt[15]。 3.一般二叉树的顺序存储 (1) 具体方法 ① 将一般二叉树添上一些 "虚结点",成为"完全二叉树" ② 为了用结点在向量中的相对位置来表示结点之间的逻辑关系,按完全二叉树形式给结点编号 ③ 将结点按编号存入向量对应分量,其中"虚结点"用"∮"表示 (2) 优点和缺点 ① 对完全二叉树而言,顺序存储结构既简单又节省存储空间。 ② 一般的二叉树采用顺序存储结构时,虽然简单,但易造成存储空间的浪费。 【例】最坏的情况下,一个深度为k且只有k个结点的右单支树需要2k-1个结点的存储空间。 ③在对顺序存储的二叉树做插入和删除结点操作时,要大量移动结点。 链式存储结构 1.结点的结构 二叉树的每个结点最多有两个孩子。用链接方式存储二叉树时,每个结点除了存储结点本身的数据外,还应设置两个指针域lchild和rchild,分别指向该结点的左孩子和右孩子。结点的结构为: 2.结点的类型说明 typedef char DataType; //用户可根据具体应用定义DataType的实际类型 typedef struct node{ DataType data; Struct node *lchild,*rchild; //左右孩子指针 }BinTNode; //结点类型 typedef BinTNode *BinTree;//BinTree为指向BinTNode类型结点的指针类型 3.二叉链表(二叉树的常用链式存储结构) 在一棵二叉树中,所有类型为BinTNode的结点,再加上一个指向开始结点(即根结点)的BinTree型头指针(即根指针)root,就构成了二叉树的链式存储结构,并将其称为二叉链表。 【例】下面左图所示二叉树的二叉链表如下面中图所示。 注意: ① 一个二叉链表由根指针root惟一确定。若二叉树为空,则root=NULL;若结点的某个孩子不存在,则相应的指针为空。 ② 具有n个结点的二叉链表中,共有2n个指针域。其中只有n-1个用来指示结点的左、右孩子,其余的n+1个指针域为空。 4.带双亲指针的二叉链表 经常要在二叉树中寻找某结点的双亲时,可在每个结点上再加一个指向其双亲的指针parent,形成一个带双亲指针的二叉链表。 【例】上面右图是上面左图所示的二叉树的带双亲指针的二叉链表。 注意: 二叉树存储方法的选择,主要依赖于所要实施的各种运算的频度。 |