在信奥赛中,我们会接触到一种很常见,很基础的数据结构,它就是树。
树是什么?
树是无环连通图。
树可以怎么分类?
树可以分成:
- 有根树和无根树
- n叉树
- ……
树有哪些特殊性质?
- 树的边数 = 树的点数 - 1
- 树的两点之间存在唯一路径
- ……
树是很清晰的,也是复杂的,树的问题或许十分简单,比如求父节点(好吧,没有这样的问题),也有很复杂的数据结构,比如说红黑树,是需要我们多练习的。
在了解了以上问题后,让我们切入正题,树的存储方式有哪些?
树的存储方式
邻接表
我们知道,存图主要有三种方式:邻接矩阵、邻接表和链式前向星(不讲)。邻接矩阵十分占用空间,它的空间复杂度是O(n^2)的,树是一种典型的稀疏图,用邻接矩阵存树十分浪费,而且在树的应用中也不占优势;而邻接表比较节省空间,而且实现简单,是存树的不二选择。
孩子兄弟表示法
我们可以开一个结构体数组:
struct Node {
int bro;
int son;
} tree[N];
结构体Node里面有两个数据,分别是Bro和Son,分别存储着它的下一个兄弟和儿子的下标。
e.g.
1
| | | |
2 3 4 5
| | | |
6 7 8 9
其中tree[2]的bro是3,son是6,代表2号节点的下一个兄弟节点的下标是3,而它的第一个子节点的下标是6。
对于tree[6]而言,它是叶子节点,因此son为0(当然也可以是-1或者是任意一个代表无子结点的数),但是它有下一个兄弟节点,因此bro为7。
对于tree[5]而言,它不是叶子节点,有子节点9,因此son为9,而它却没有下一个兄弟节点,因此bro为0。
对于tree[7]而言,它既是叶子节点,又没有下一个兄弟节点,因此son和bro都为0。
注意:孩子兄弟表示法是对有根树而言的。
有根树和无根树的区别
有根树存在根节点;无根树则类似与图,没有根节点,比如说:
1
| |
2 3
和
2
|
1
|
3
是同一棵树(如果它们都是无根树)。
双亲表示法
请注意,虽然名为双亲表示法,实际上只有“单亲”,也就是存储节点的父节点。
int fa[N];
我们可以通过一个普通的数组来存储一棵树,而fa[i]也就是i的父节点,这种存储方式可以很快地获取到父节点,但不能很快地获取到子节点。
e.g.
1
| | | |
2 3 4 5
| | | |
6 7 8 9
还是用刚刚的那个例子。
index | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
fa[index] | 0 | 1 | 1 | 1 | 1 | 2 | 2 | 3 | 5 |
很明显,fa[i]就是i的父节点。
总结
今天我们讨论了树的定义、性质和最重要的树的表示方式。我们得知树的主要表示形式有
- 邻接表
- 孩子兄弟表示法
- 双亲表示法
了解了他们之间的区别。希望大家能勤加练习,在这条路上越走越远!
Time to 点赞
看完后,别忘了
点赞!
收藏!
Thanks……