目录
1.1二叉树的定义
给一般的二叉树加上两个限制条件就可以得到二叉树:
(1)每个结点最多只有两颗子树,即二叉树中结点的度只能为0,1,2。
(2)子树有左右顺序之分,不能颠倒。
满二叉树 | 在一棵二叉树中,所有的分支结点都有左孩子结点和右孩子结点,并且叶子结点都集中在二叉树的最下一层。例如,图6-4a就是一颗满二叉树。 |
完全二叉树 | ① 对一棵深度为k的满二叉树编号。(从上到下,从左至右,从1开始。) ② 对一棵深度为k、有n个结点的二叉树编号。 ③ 若②中各结点的编号与①中相同位置上结点的编号都相同。 那么,②中的树为完全二叉树。 |
一棵完全二叉树是由一棵满二叉树,从右至左,从下往上,逐个删除结点所得到的。如果跳着删,则得到的不是完全二叉树。
1.2二叉树的主要性质
性质1:非空二叉树上叶子结点数等于双分支结点数+1。
证明: 1、设二叉树中叶子结点的个数为 N0,单分支结点的个数为N1,双分支结点的个数为N2。
那么,总结点的个数= N0+N1+N2。
2、 在二叉树中,所有结点的分支数=1*单分支结点的个数 + 2*双分支结点的个数。
即 总分支数=N1+2N2。
3、 在二叉树中,除了根节点,每个结点都有一个分支指向它。 即 总分支数=总结点数-1=N0+N1+N2-1。
(该条结论适用于所有的树)
所以,总分支数=N1+2N2=N0+N1+N2-1。
得出, N0=N2+1。
性质二:二叉树的第 i 层上最多有
(
)个结点。
结点最多的情况就是满二叉树的情况,此时,二叉树上每一层的结点数就构成了一个
首项为1、公比为2 的等比数列,通项为 ,i为层数。
性质三:高度(深度)为k的二叉树,最多有
(
) 个结点。也就是,满二叉树前 k 层的结点个数为
。
由刚刚性质二中的,等比数列求和可以算出,前k项和为 。
性质四:完全二叉树中,某结点的双亲结点、左孩子结点、右孩子结点。
有 n 个结点的完全二叉树,对各结点从上往下,从左至右,依次编号,编号范围为 1~n。设 i 为某结点 a 的编号,则:
①
,则 a 双亲结点的编号为
。
②
,则 a 的左孩子结点编号为
。
,则 a 无左孩子结点。
③
,则 a 的右孩子编号为
。
,则 a 无右孩子结点。
性质五:函数Catalan():给定 n 个结点,能构成 h(n) 种不同的二叉树,
。
性质六:具有 n (n>=1) 个结点的完全二叉树的高度(深度)为
。
1.3二叉树的存储结构
1.3.1 顺序存储结构
用一个数组来存储一棵二叉树,这种存储方式最适合于完全二叉树,存储一般的二叉树会浪费大量的存储空间。
将完全二叉树中的结点值按照编号依次存入一个一维数组中,就完成了一棵二叉树的顺序存储。
例如,知道了结点A的下标为1,要得到A的左孩子结点只需要访问BTree[2*i]即可。
类似的,当知道一个结点的下标为 i 时,若2i <=n ,那么 i 的左孩子结点就存在BTree[2*i]中。
1.3.2 链式存储结构
data表示数据域,用来存储对应的数据元素;lchild和rchild分别表示左指针域和右指针域,
分别用于存储左孩子结点和右孩子结点的位置。
这种结构又称为二叉链表存储结构。
对应的结点类型定义为:
typedef struct BTNode
{
char data;
struct BTNode *lchild;
struct BTNode *rchild;
}BTNode;