一般树的存储结构:
1.双亲表示法
用一组连续的空间结构存储树的结点,同时在每个结点中附设一个指示器指示其双亲结点在链表中的位置。
如下:
const int Max_Tree_Size = 100;
struct TNode {
int date;
int parent;//用来存储双亲的位置.
};
struct Tree {
TNode node[Max_Tree_Node];
int r,n;//r为根的位置,r为结点的个数
}tree;
这种存储结构利用了每个结点(除根以外)只有唯一双亲的性质。
优点:可以再常量时间内找到双亲结点。
缺点:如果需要求孩子结点的时候需要遍历整个结构。
2.孩子表示法
由于树中每个结点可能有多棵子树,所有可以用多重链表,即每个结点有多个指针域,其中每个指针指向一棵子树的根结点,这时候链表 中的结点可以有如下两种结点格式:
1.
const int Tree_Dep = x;
struct Node {
int date;
Node *children[d];//树的深度为d
};
每个结点都是同构的。
由于树中的结点的度很多都小于d,所以空间比较浪费,可以推出在含有n个结点中的树中含有(d-1)*n+1空链。
2.
struct Node {
int date;
int degree;
Node *children[degree];//树的深度为d
};
每个结点都的不同构的。
虽然节省了空间,但是操作起来很的不方便。
还有一种方法,简单来说就是单链表来模拟vector来存储树。不在详细做解释。。。
孩子表示法的优点:便于那种涉及孩子的操作的实现。
3.孩子兄弟表示法
又称为二叉树表示法,或二叉链表表示法。就是一二叉链表做为树的存储结构。
链表中结点的两个链域分别指向该结点的第一个孩子和下一个兄弟结点。
如下:
struct Node {
int date;
Node *firstchild, *nextsibling;
};
优点,易于实现找结点孩子的操作。
二叉树的存储结构:
1.顺序存储结构
const int Max_Tree_Size = 100;
int tree[Max_Tree_Size];
其实就是用一个数组来存储树,下标即为特定的结点。
这种顺序存储结构仅适用于完全二叉树。因为在最坏的情况下,一个深度为k且有k个结点的单支树却需要长度为2^k-1的一维数组。
2.链式存储结构
a.二叉链表
struct Node {
int date;
Node *leftchild, *rightchild;
};
可以证明,一个含有n个结点的二叉链表中有n+1个空链域。
b.三叉链表
struct Node {
int date;
Node *leftchild, *rightchild, *parent;
};
三叉链表更易于找到结点的双亲。