最近开始学习王争老师的《数据结构与算法之美》,通过总结再加上自己的思考的形式记录这门课程,文章主要作为学习历程的记录。
树是一种非线性表结构。树这种数据结构比线性表的数据结构要复杂得多。
树中的每个元素叫做“节点”,用来连线相邻节点之间的关系,叫做“父子关系”。如上图,A节点是B节点的父节点,B节点是A节点的子节点。B、C、D这三个节点的父节点是同一个节点。因此,它们互称兄弟节点。把没有父节点的节点叫做根节点,也就是图中的节点E。将没有子节点的节点叫做叶子节点或叶节点,其中G、H、I、J、K、L均为叶子节点。
关于树,还有三个比较相似的概念:高度、深度和层,定义为:
节点的高度 = 节点到叶子节点的最长路径(边数)
节点的深度 = 根节点到这个节点所经历的边的个数
节点的层数 = 节点的深度+1
树的高度 = 根节点的高度
以下图为例
树的结构多种多样,最常用的还是二叉树。二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,左子节点和右子节点。
其中,叶子节点均在最底层,除了叶子节点之外,每个节点都有左右两个子节点。这种二叉树叫做满二叉树。如下图中②:
叶子节点都在最底下两层,最后一层的叶子节点都靠左排列,并且除了最后一层,其他层的节点个数都要达到最大,这种二叉树叫做完全二叉树,如上图③。
要理解完全二叉树定义的由来,需要了解如何表示(或存储)一棵二叉树?
想要存储一棵二叉树,有两种方法:一种是基于指针或引用的二叉树链式存储法,一种是基于数组的顺序存储法。首先看一下比较简单,直观的链式存储法,每个结点有三个字段,其中一个存储数据,只要拎着根节点,就可以通过左右子节点的指针,把整棵树串起来。
接下来,再看基于数组的顺序存储法。我们把根结点存储在下标为i的位置,那左子节点存储在下标 2 ∗ i = 2 2*i=2 2∗i=2的位置,右子节点存储在 2 ∗ i + 1 = 3 2*i+1=3 2∗i+1=3的位置。以此类推,B节点的左子节点存储在 2 ∗ i = 2 ∗ 2 = 4 2*i=2*2=4 2∗i=2∗2=4的位置,右子节点存储在 2 ∗ i + 1 = 2 ∗ 2 + 1 = 5 2*i+1=2*2+1=5 2