树的定义
n(n>=0)个结点构成的有限集合,非线性数据结构,n=0时为空树
对于任意一棵非空树具备以下性质:
有一个Root,用r表示
其余结点可分为m个互不相交的有限集T1,T2, ... ,Tm,其中每个集合本身又是一棵树,称为原来树的子树SubTree
判定树与非树?
子树不相交
除了根结点外,每个节点有且仅有一个父结点
一棵N个结点的树有N-1条边
树是保证结点连通的最少边的方式
树的基本术语
结点的度(degree):结点的子树个数
树的度:数的所有结点中最大的度数
叶结点(leaf):度为0的结点,也叫终端结点
非终端结点:也叫分支结点,指度不为0的结点。除了根结点外的终端结点也叫内部结点
父结点(parent)、子结点(child)
兄弟结点(sibling):具有同一parent的各个结点彼此互为sibling
路径和路径长度:从结点n1到nk的路径为一个结点序列n1,n2, ... ,nk,ni是ni+1的父结点。路径所包含边的个数为路径长度
祖先结点(ancestor):沿树根到某一结点路径上的所有结点都是这个结点的祖先结点
子孙节点(descendent):某一结点的子树中的所有结点时这个结点的子孙
结点的层次(level):即以该结点为根的层数,根节点算1层
树的深度/高度(depth):树所有结点中最大层次是这棵树的深度
堂兄弟:父结点在同一层的两个结点互为堂兄弟
有序树:树中结点的子树从左到右有次序无法互换
无序树:树中结点的子树没有顺序可以任意交换
丰满树:理想平衡树,要求除最底层外其他层都是满的
森林:若干棵互不相交的树的集合
树的表示方法(存储结构)
顺序存储结构
双亲存储结构
利用结构体数组和字符型数组实现,前者存储结点关系信息,后者在结点是字符型时完成字符到数组下标的映射
typedef struct {
int Data;
int Parent;
} Tree;
char Data[maxsize];
Tree tree[maxsize];
简单情况下也可以用一维数组存储一棵树的信息。数组下标表示树的结点,数组元素的内容表示该结点的Parent
int tree[maxsize];
注意:树的双亲存储结构在Kruskal算法中有重要应用!
链式存储结构
儿子存储结构
typedef struct Node *Tree;
typedef Tree Position;
typedef int ElementType;
typedef struct{
ElementType Element;
Tree child1;
Tree child2;
...;
} Node;
儿子兄弟存储
typedef struct Node *Tree;
typedef Tree Position;
typedef int ElementType;
typedef struct{
Tree firstchild;
Tree nextsibling;
} Node;
注意:如果实现的时候全部用每个结点含三个指针域,那么n个结点有n-1个边,3n个指针域,利用率太低;儿子-兄弟存储结构,n个结点2n个指针域,利用率提高