数据结构-树的存储结构

159 阅读3分钟

树的存储结构

前面几篇文章,我介绍了树这一数据结构中二叉树的部分。二叉树是树当中最基础、最关键的数据结构。然而树并不只有二叉树这一种形式,而且每个分支结点的孩子结点也并不一定只有两个甚至是更少。本文将记录树是如何在计算机当中实现的。

树的存储方式十分多样,以下几种方式都是从树的逻辑结构角度出发来实现的。

双亲表示法

#define maxSize 50

struct node_t_p {//树结点结构体
	int data , parent;
};
struct tree_p {//树结构体
	int n;
	node_t n [maxSize];
};

以上的方法是用顺序存储的方式实现的,由于每个结点的双亲结点是唯一的,所以树的结点结构体除了存放结点的数据,还存放着顺序表中双亲结点的下标。

这样的好处是很容易知道一个指定结点的双亲结点在顺序表中的位置和存放的数据;但是,如果想寻找到指定结点的孩子结点所存放的数据,则需要重新遍历整个树,因为结构体中并没有该结点孩子对应的位置(而且树结点的孩子结点并不唯一,这是与双亲结点最大的区别)。

孩子表示法

#define maxSize 50

struct node_t_c {//树结点结构体
	int data;
	node_t_c_ch *child;
};

struct node_t_c_ch {//孩子结点下标链表
	int pos;
	node_t_c_ch *next;
};

struct tree_c {//树结构体
	int n;
	node_t_c [maxSize];
};

这种方法从结点的孩子结点的角度出发,不过由于一个结点的孩子结点可能有多个,而且数量尚不明确,所以结点的孩子结点的下标就用链表的形式进行存储。所以,孩子表示法我们可以采用顺序存储和链式存储相结合的方式来实现。

这种存储方式的优点和缺点基本上和双亲表示法相反,即想找到指定结点的孩子结点比较容易,但是想找到指定结点的双亲结点比较困难,需要将整个链表重新遍历一遍。

孩子兄弟表示法

struct node_t_cb {
	int data;
	node_t_cb *firstChild,*rightBro;
};

又称为二叉树表示法,这种方法使用二叉链表作为存储结构。结点包括数据data、指向第一个孩子结点的指针firstChild和指向该结点右兄弟结点的指针rightBro

由于结点采用二叉链表的方式进行存储,这种方法相较于孩子表示法,可以使树更容易转成我们所熟悉的二叉树。缺点就是当想寻找指定结点的双亲结点时,比较困难。

我们可以对链表结点进行改造,增加一个指针域par来指向该结点的双亲结点,这样寻找指定结点的双亲结点也会比较方便。