文章目录
一、树的概念
1.树的性质
(5)树的度为m 与m叉树的区别
(6)
- 高度为h的m叉树,至少有
h
个结点 - 高度为h、度为m的树,至少有
h+m-1
个结点
重点:再次体会度为m、与m叉树的不同
2.练习题
二、二叉树
1.二叉树的定义
- 二叉树是有序树,左右次序不能颠倒。
二叉树与度为2的有序树的区别:
- 度为2的树至少有3个结点
- 度为2的有序树的孩子的左右次序是相对于另一个孩子而言的,若某个结点只有一个孩子,则这个孩子就无须区分其左右次序,而二叉树无论其孩子数是否为2.均需确定其左右次序,即二叉树的结点次序不是相对另一个结点而言,而是(绝对)确定的。
总结:
度为2的有序树,次序是相对地
二叉树,次序是绝对地
2.几个特殊二叉树
(1) 满二叉树 vs 完全二叉树
- 满二叉树最下层都是满的
- 完全二叉树只有最下层、倒数第二层不一定是满的
完全二叉树的编号和满二叉树是一一对应的。
完全二叉树相当于按照编号从小到大、从左到右去依次放入结点,不能跳过、空过一个位置而在下一个位置放入。
实际上,在满二叉树的基础上,把编号最大的结点,依次序删掉,就变成了一颗完全二叉树了。例如,下面左图中去掉 15、14、13结点后就成为一颗完全二叉树。但是去掉 15、13、12后就啥也不是、沦为一颗普普通通二叉树了。
- 完全二叉树的性质
若
i<= |n/2」
,则结点 i 为分支结点,否则为叶子结点。叶子节点只可能在最底下两层出现。
若有度为 1 的结点,则只可能有一个,且该结点只有左孩子而无有孩子(重要特征)。
按层序编号后,一旦出现某结点(编号为i)为叶子结点或只有一个左孩子,则编号大于 i 的结点均为叶子结点。
若n为奇数,则每个分支结点都有左孩子、右孩子;若n为偶数,则编号最大的分支结点(编号为n/2)只有左孩子,没有右孩子,其余分支结点左、右孩子都有。(n为结点总数)
(2)二叉排序树
定义:一棵二叉树或者是空二叉树,或者是具有如下性质的二叉树:
左子树
上所有结点的关键字均小于
根结点的关键字;右子树
上所有结点的关键字均大于
根结点的关键字。- 左子树和右子树又各是一棵二叉排序树。
- 二叉排序树可用于元素的排序、搜索。
(3)平衡二叉树
3.二叉树的性质
重点看完全二叉树的性质
4.二叉树的存储
(1)顺序存储
顺序存储就是用一组连续的存储单元依次自上而下、自左至右存储完全二叉树上的结点。
比如,数组下标对应结点编号。
先说结论:
- 顺序存储只适用于完全二叉树和满二叉树
- 对于一般二叉树,为了能让数组下标能够反映二叉树中的结点之间的关系,只能添加一些并不存在的空结点,让其每个结点的位置与完全二叉树结点位置对齐。
所以,对于一般二叉树,最坏的情况 h 高度且只有 h 个结点的单分支树,仍然需要开辟
2^h-1
个存储单元。
(2)链式存储
typedef struct BiTNode{
ElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
重要结论:含有n个结点的二叉链表中,含有 n+1 个空链域。
n个结点,共2n个指针域。
n个结点的度数为 n-1 ,所以空指针域 = 2n - (n-1) = n+1
struct ElemType{
int value;
}
typedef struct BiTNode{
ElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
//定义一颗空树
BiTree root = NULL;
root = (BiTree)malloc(sizeof(BiTNode));
root->data = {
1};
root->lchild = NULL;
root->rchild = NULL;
//插入左结点
BiTNode *p = (BiTree)malloc(sizeof(BiTNode));
p->data = {
2};
p->lchild