漫谈数据结构——二叉树

122 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情

前言

我们认识完树的概念后,明白树的一个具体表现,树有很多种实现,有二叉树,红黑树,AVL树等等,树各种数据结构在特定的场景下都表现的非常优异,那么我们今天就来谈一下其中的一种实现——二叉树。

二叉树

二叉树,从名字中就可以非常形象的得知,它的每个节点最多有两个字节点,分别是左子节点和右子节点。不过并不要求每个节点都必须要有两个字节点,除去叶子节点外,可以只有左子节点或者只有右子节点。以此类推,四叉树,八叉树的具体概念也可以套用二叉树的概念进行延伸。

二叉树的种类

二叉树有两种特别的种类,分别是满二叉树和完全二叉树。

  • 满二叉树的定义如下:叶子节点全部都在低层,除去叶子节点外,每个节点都具有左子节点和右子节点。这种二叉树称之为满二叉树
  • 完全二叉树:叶子节点都在底层,除叶子节点外以及叶子节点的父节点外,每个节点必须都要具有左子节点和右子节点。并且叶子节点需要靠左排列(涉及到二叉树的存储)。

二叉树的存储

二叉树也有两种存储方式,一种是依靠链表的方式存储,一种是依靠数组的方式存储。

  • 链表方式存储:链表方式存储是非常常见的,就是定义一个节点对象,里面存储数据data以及存储左子节点对象和右子节点对象。
  • 基于数组的顺序存储:为了计算方便,把根节点放在下标i=1的地方。左子节点存储的下标就是2 * i = 2的位置,右子节点存储的下标就是 2 * i + 1 = 3的位置。因为B的节点索引为2,那么它的左子节点存储的下标位置是2 * 2 = 4,右子节点存储的下标位置是 2 * 2 + 1 = 5的位置,依次类推,将整个二叉树存储在数组中。

二叉树的遍历

二叉树的遍历方式有三种:分别是前序遍历,中序遍历,后序遍历。

  • 前序遍历:先遍历自己,再遍历左子树,再遍历右子树。
  • 中序遍历:先遍历左子树,在遍历自己,在遍历右子树。
  • 后序遍历:先遍历左子树,在遍历右子树,最后再遍历自己 对于使用代码去遍历树结构,我们必须要先推到出递归公式,然后再开始编写代码。
// 前序遍历
preTraverse(r) = print r, preTraverse(r->left), preTraverse(r->right)
// 中序遍历
inTraverse(r) = inTraverse(r->left), print r,  inTraverse(r->right)
// 后序遍历
postTraverse(r) = postTraverse(r->left),  postTraverse(r->right), print r

根据以上的三个公式,我们就可以快速写出对应的递归代码了。

总结

今天我们认识到了树的一种实现——二叉树。