数据结构复习:树的简单介绍
表示方法:
(1)树形表示法: 简单直接的树形图
(2)文氏图表示法: 韦恩图
(3)凹入表示法
(4)括号表示法: 根(子树1,子树2(。。。。))
性质:
1.结点数等于所有结点的度之和加1
度表示有多少个子结点,子结点的和加上根即为树的总结点数
2.度为m的树中第i层上最多有m^(i-1)个结点
3.高度为h的m次树最多有(m^h-1)/(m-1)
4.具有n个结点的m次树的最小高度为 [log~m(n(m-1)+1)].
由性质3,若树的每一层都是满的,则可以得出m与n的关系。
运算
寻找、插入、删除、遍历
存储结构:
1.双亲存储结构:
typedef struct
{
ElemType data; //存放结点的值
int parent; //存放双亲的位置
}PTree[MaxSize]; //PTree为双亲存储结构类型
优点:节省空间、寻找双亲结点十分容易
缺点:求孩子结点需要遍历整个存储结构
孩子链存储结构:
typedef struct node
{
ElemType data; //结点的值
struct node * sons[MaxSons] //指向孩子结点,结点的个数由树的度决定
}TSonNode;
优点:查找孩子结点方便
缺点:查找双亲结点费时、空间利用率不高
例: 求树 t 高度的递归算法
int TreeHeight1(TSonNode * t)
{
TSonNode * p;
int i, h, maxh = 0;
if(t==null)return 0; //空树返回0
else
{
for(i=0; i<MaxSons; i++)
{
p=t->sons[i]; //访问根节点的每一个子树
if(p!=null)
{
h=TreeHeight(p); //求子树的高度
if(maxh<h) maxh=h; //求所有子树的最大高度
}
}
}
return maxh+1; //最后加上根节点的高度
}
孩子兄弟链存储结构
typedef struct tnode
{
ElemType data; //结点的值
struct tnode * hp; //指向兄弟
struct tnode * vp; //指向孩子结点 ->最左边的长子
}TSBNode;
优点:可实现二叉树和树的转换。
缺点:不容易查找双亲结点
例:求树 t 高度的算法
int TreeHeight2(TSBNode * t)
{
TSBNode * p;
int h, maxh=0;
if(t==null) return 0;
else
{
p=t->vp; //p指向第一个孩子结点
while(p!=null) //扫描所有的子树
{
h=TreeHeight2(p); //求出p子树的高度
if(maxh<h) maxh=h;
p=p->hp //指向兄弟结点(即t的其他子结点)
}
}
return maxh+1;
}
两个函数功能基本相同,但是因为树的存储结构不同,所以算法设计上存在差异