为什么使用树
采用“树”(分层次)的管理方法,在数据管理上具有最高的效率
什么是树
注意
树的一些基本术语
树的表示
儿子-兄弟表示法
树上的每个节点的结构是统一的,有2个指针域,左边指向他的第一个儿子,右边指向他的兄弟
二叉树
二叉树的定义:度为2,也就是每个结点指针最多是2个
特殊二叉树
斜二叉树
都只有左儿子或都只有右儿子,实际上相当与是个单链表,是一个线性结构
完美二叉树
除最低下这一层的叶节点(无儿子)以外,其他结点都有2个儿子,并且叶节点都在同一层
完全二叉树
完全二叉树不是完美二叉树,允许缺掉完美二叉树最下层的叶节点
例如
如果同一位置的编号和完美二叉树的编号不同,则不是完美二叉树
二叉树的几个重要性质
二叉树的存储结构
顺序存储结构(数组)
缺点:对于非完全二叉树,可能会有这边缺一些,那边缺一些的情况, 用该方法,则对于相应缺的结点,在数组里面留下一个空位,造成一定空间浪费
链式存储结构(链表)
有1个数据域,存储该节点的值,2个指针域,分别存储左右儿子的地址,若无左右儿子,则为NULL
二叉树的遍历
遍历的重要性:在二叉树的求解很多问题的解析方法是建立在树的遍历的基础上
核心问题:二维结构的线性化
二叉树的常见遍历方法
先序遍历(递归)
BT为传递进来的节点地址,先判断该节点是否为空,如果不空,则先访问该节点(也就是printf输出),然后先后对该节点的左子树和右子树递归
中序遍历
后序遍历
先 中 后 序的区别在于:访问(也就是printf输出)的顺序不一样,不过遍历过程中经过结点的路线一样
层次遍历
队列实现
数组实现
void LevelorderTraversal(BinTree BT){
if(BT==NULL)//BT=NULL不要忘记
return;
BinTree Q[1000];
int front,rear;
front=rear=-1;
Q[++rear]=BT;
BinTree p;
while(front<rear){
p=Q[++front];
printf(" %c",p->Data);//输出该结点
if(p->Left)//判断是否为空{
Q[++rear]=p->Left;//将该节点的左儿子地址存入数组
}
if(p->Right)//判断是否为空{
Q[++rear]=p->Right;//将该节点的右儿子地址存入数组
}
}
}
遍历二叉树的应用
输出二叉树中的叶子节点
在二叉树的遍历算法中添加检测结点的左右子树是否都为空
求二叉树的高度(递归)
代码
int GetHeight(BinTree BT){
int cnt =0;
if(BT){
int l,r;
l=GetHeight(BT->Left);
r=GetHeight(BT->Right);
if(l>r)cnt=l+1;else cnt=r+1;
}
return cnt;
}