数据结构与算法——树和二叉树
一、树的定义
1、定义:树是n个结点的有限集。
若n=0,称为空树;
若n>0,则它满足如下两个条件:
(1)有且仅有一个特定的称为根的结点
(2)其余结点可分为m(m>=0)个互不相交的有限集T1,T2,T3,……,Tm,其中每一个集合本身又是一棵树,并称为根的子树
2、根节点:非空树中无前驱结点的结点
3、结点的度:结点拥有的子树数
4、树的度:树内各结点的度的最大值
5、度=0的结点称为叶子或终端节点
6、孩子:结点的子树的根称为该结点的孩子,该结点称为孩子的双亲
7、树的深度:树中结点的最大层次
8、有序树:树中结点的各子树从左至右有次序(最左边的为第一个孩子)
9、无序树:树中结点的各子树无次序
10、森林:是m(m>=0)棵互不相交的树的集合
二、二叉树的定义
1、二叉树:是n个结点的有限集,它或者是空集(n=0),或者由一个根结点及两棵互不相交的分别称作这个根左子树和右子树的二叉树组成。
2、特点:
(1)每个结点最多有两个孩子
(2)子树有左右之分,其次序不能颠倒
(3)二叉树可以是空集合,根可以有空的左子树或空的右子树
3、二叉树的性质
(1)性质1:在二叉树的第i层上至多有个结点(i>=1)
(2)性质2:深度为k的二叉树至多有个结点(k>=1)
(3)性质3:对任何一棵二叉树T,如果其叶子数为n0,度为2的结点数为n2,则n0=n2+1。
4、满二叉树:一棵深度为k且有个结点的二叉树称为满二叉树
5、满二叉树的特点:
(1)每一层上的结点都是最大结点数(即每层都满)
(2)叶子结点全部在最底层
6、完全二叉树:深度为k的具有n个结点的二叉树,当且仅当其每一个结点每一个结点都与深度为k的满二叉树中编号1~n的结点一一对应时,称之为完全二叉树。
7、完全二叉树的特:
(1)叶子只可能分布在层次最大的两层上
(2)对任一结点,如果其右子树的最大层次为i,则其左子树的最大层次必为i或i+1
8、完全二叉树的性质
性质:具有n个结点的完全二叉树的深度为
三、二叉树的顺序存储
1、二叉树的顺序存储实现:按满二叉树的结点层次编号,依次存放二叉树中的数据元素。
#define MAXSIZE 100
typedef char TElemType;
typedef TElemType SqBiTree[MAXSIZE];
SqBiTree bt;
2、二叉树的顺序存储缺点:最坏情况:深度为k的且只有k个结点的单支树需要长度为的一维数组。
3、特点:结点空间关系蕴含在其存储位置中浪费空间,适用于存储满二叉树和完全二叉树
四、二叉树的链式存储结构
1、二叉树链表存储结构
typedef char TElemType;
typedef struct BiNode {TElemType data;struct BiNode* lchild, * rchild;//左右孩子指针
}BiNode,*BiTree;
2、在n个结点的二叉链表中,有n+1个空指针域
分析:必有2n个链域。除根结点外,每个结点有且仅有一个双亲,所以只会有n-1个结点的链域存放指针,指向非空子女结点。空指针数目=2n-(n-1)=n+1
3、三叉链表存储结构
typedef char TElemType;
typedef struct TriTNode {TElemType data;struct TriTNode* lchild, *parent,* rchild;//左右孩子指针
}TriTNode,*TriTree;
五、遍历二叉树
1、遍历方法
假设:L为遍历左子树;D:访问根结点;R:遍历右子树
若规定先左后右,则