树和二叉树
- 树的定义和基本语句
- 二叉树
- 遍历二叉树和线索二叉树
- 树和森林
- 霍夫曼树及其应用
树的定义和基本语句
树是n个结点的有限集
树的表示方法
基本术语
根:即根节点(没有前驱)
叶子结点:即终端节点(没有后继)
森林:是有n棵树的集合
树的深度:所用节点层数中的最大值
二叉树
基本特点:
节点的度小于等于2
子树有序
二叉树的性质
1,在二叉树的第i层上至多有2^(i - 1)个结点(除叶子结点外,其余子树的度都为2)
2,深度为k的二叉树至多有2^k - 1个结点(总共的节点数)
3,对于任何一棵二叉树,若度为2的结点数有n2个,那度为0的节点数=度为2的结点个数 +
满二叉树:一棵深度为k且有2^k - 1个结点的二叉树
完全二叉树:深度为k的,有n个结点的二叉树,当且仅当每一个节点斗鱼深度为k的满二叉树中的编号一一对应
满二叉树是叶子结点一个也不少的树,而完全二叉树虽然k - 1层是满的但是最底层却允许在右边缺少连续若干结点
满二叉树是完全二叉树的特例
4,具有n个结点的完全二叉树的深度必为log2 n + 1
5,对于完全二叉树,若从上之下,从左到右编号,则编号为i的结点,其左孩子编号必为2*i,其右孩子编号必为2 * i + 1,其双亲的编号必为i / 2
6,完全二叉树度为1的结点个数最多是1个
练习题
一棵完全二叉树有5000个结点,可以计算出其叶子结点的个数()
方法1,我们可以对着5000个结点进行编号,所以我们可以求最后一个节点得双亲结点的编号是2500,如果在2500后面还有双亲那它的子结点的编号肯定比5000大,所以2500后就没有双亲有结点了,所以5000 - 2500 = 叶子结点
方法2:n0 = n2 + 1;
由性质六可知 n1 = 1
5000 = n0 - 1 + n0 + 1
n0 = 2500
二叉树的存储
顺序存储
我们在内存中根据满二叉树中二叉树位置的编号开辟连续的空间并按照结点所对应的编号进入对应的空间中
弊端:如果二叉树不是完全二叉树或满二叉树这样开辟就太浪费空间了.
链式储存
我们开辟一个空间,里面存放三个东西:左孩子的地址,结点的信息,右孩子的地址
遍历二叉树和线索二叉树
用递归实现二叉树的遍历代码如下
#include <stdio.h>
#include <stdlib.h>
typedef struct BiTree{
int data;
struct BiTree *lchild,*rchild;
}BiTree;
typedef BiTree *SuTree;//定义树
void ChuangJian(SuTree &s)
{
char ch;
scanf("%c",&ch);
if(ch == '#')
{
s = NULL;
}
else
{
s = (SuTree)malloc(sizeof(BiTree));
if(!s)
{
return;
}
s -> data = ch;
ChuangJian(s -> lchild);
ChuangJian(s -> rchild);
}
}
void Qian(SuTree s)
{
if(s == NULL)
{
return;
}
else
{
printf("%c ",s -> data);