二叉树的存储方式
存储一棵二叉树有两种方法,一种是基于指针或者引用的二叉链式存储法,一种是基于数组的顺序存储法。
链式存储法
用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。二叉链
每个节点有三个字段,其中一个存储数据,另外两个是指向左右子节点的指针。
顺序储存法
顺序结构存储就是使用数组来存储。
我们把根节点存储在下标 i = 1 的位置,那左子节点存储在下标 2 * i = 2 的位置,右子节点存储在 2 * i + 1 = 3 的位置。
以此类推,B 节点的左子节点存储在 2 * i = 2 * 2 = 4 的位置,右子节点存储在 2 * i + 1 = 2 * 2 + 1 = 5 的位置。
如果节点 X 存储在数组中下标为 i 的位置,下标为 2 * i 的位置存储的就是左子节点。
下标为 2 * i + 1 的位置存储的就是右子节点。
反过来,下标为 i/2 的位置存储就是它的父节点。
通过这种方式,我们只要知道根节点存储的位置,就可以通过下标计算,把整棵树都串起来。
(一般情况下,为了方便计算子节点,根节点会存储在下标为 1 的位置)
为什么会有完全二叉树这一概念,而且要求完全二叉树最后一层的节点要全部靠左排列呢?
关于刚才的顺序存储法,列举的是一个完全二叉树的例子。若是非完全二叉树呢?
可以看出来,非完全二叉树会浪费很多的存储空间。
而完全二叉树仅仅只”浪费“了下标为0的位置。
顺序存储法的优势就是并不像链式存储法那样,要存储额外的左右子节点的指针。
所以,某棵二叉树是一棵完全二叉树,那用数组存储无疑是最节省内存的一种方式。
这也是为什么完全二叉树会单独拎出来的原因,也是为什么完全二叉树要求最后一层的子节点都靠左的原因。
堆其实就是很好的体现,堆其实就是一种完全二叉树,最常用的存储方式就是数组。