树的存储结构
只考虑顺序存储结构和链式存储结构,要考虑双亲、孩子、兄弟之间的关系,有三种表示法:双亲表示法、孩子表示法、孩子兄弟表示法。
双亲表示法:
以双亲作为索引的关键词的存储方式, 每个节点的存储的数据 “data”+ 它的双亲的位置“parent”指针, 前序遍历(左序遍历)
位序 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|---|
结点data | A | B | E | H | I | J | C | D | F | G | K |
parent指针 | -1 | 0 | 1 | 2 | 2 | 2 | 0 | 0 | 7 | 7 | 9 |
根据某结点的parent指针找到它的双亲结点,所用时间复杂度是O(1),索引到parent的值为-1时,即找到树结点的根;
知道某结点的所有孩子,要遍历整个树;
位序 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|---|
结点data | A | B | E | H | I | J | C | D | F | G | K |
parent指针 | -1 | 0 | 1 | 2 | 2 | 2 | 0 | 0 | 7 | 7 | 9 |
rightSib | -1 | 6 | -1 | 4 | 5 | -1 | 7 | -1 | 9 | -1 | -1 |
拓展思考:这样可以实现上下左右全是O(1)
结点data | parent 指针 | firstson (第一个孩子的位置) | rightSib (右边第一个兄弟) |
孩子表示法:
每个结点可能有多棵子树,可以考虑用多重链表来实现
数组和链表搭配,链表的头结点是双亲,后面的都是他的孩子
双亲孩子表示法:
上述两者的结合,数组+链表
#define MAX_TREE_SIZE 100
typedef char ElemType;
//孩子结点
typedef struct CTNode
{
int child; //孩子结点的下标
struct CTNode *next; //指向下一个孩子结点的指针
} *ChildPtr;
//表头结构
typedef struct
{
ElemType data; //存放在数中结点的数据
int parent; //存放双亲的下标
ChildPtr firstChild; //指向第一个孩子的指针
} CTBox;
//树结构
typedef strcut
{
CTBox nodes[MAX_TREE_SIZE]; //结点数组
int r,n; //r表示根的位置,n表示结点数
}