其实这段时间一直在刷lc,但是还是感觉树图写的不太行,就重新来学习总结了。
首先提出疑问:二叉树有哪几种存储方式?什么样的二叉树适合用数组来存储?
待着问题,然后来学习今天的内容
树
我们首先来看,什么是树?再完备的定义,都没有图直观。所以请看下图的树,都有什么特征。
里面的每个实心圆点被我们称之为节点,用来连线相邻节点之间的关系,我们叫做“父子关系”。
比如下面这张图,A就是B的父亲,B就是A的孩子,而BCD的父亲都是A,所以BCD互为兄弟节点,我们把没有父节点的节点叫做根节点,也就是图中的E。我们把没有子节点的节点叫做叶子节点或者叶节点,比如图中的GHIJKL都是叶子节点。
再简单介绍下其他的
二叉树
满二叉树
完全二叉树
满二叉树,就是都画满了,但是完全二叉树呢?是不是有点概念混乱?可以对比来看:
估计很快就能看懂,那么我们就再来探讨一下二叉树的由来吧。
要理解二叉树的由来,又首先需要了解,如何表示(或者存储一棵二叉树)?
想要存储一棵二叉树,我们有两种方法,一种是基于指针或者引用的二叉链式存储法,一种是基于数组的顺序存储法。
我们先来看比较简单、直观的链式存储法。
- 链式存储法
从图中应该很清楚的就能看出,每个节点有三个字段,其中一个存储数据,另外两个是指向左右子节点的指针。我们只要拎住根节点,就可以通过左右子节点的指针,把整棵树都串起来。这种存储方式我们比较常用。大部分二叉树代码都是通过这种结构来实现的。
然后我们再来看看基于数组的顺序存储法。 我们把根节点存储在下标i=1的位置,那左子节点存储在下标2* i = 2的位置,右子节点存储在2* i+1=3的位置。以此类推,B节点的左子节点存储在2i=22=4的位置,右子节点存储在2* i+1=2* 2+1=5的位置。
说白了就是从上往下,从左到右,存储进去,,,
但是这个例子的限用条件你必须至少是一个完全二叉树,这样不会浪费存储空间,但是如果你是一个普通的二叉树,就会很占用内存空间了,如下:
当后面说到堆和堆排的时候,就会发现,堆其实就是一种完全二叉树,最常用的存储方式就是数组。
二叉树的遍历
时间复杂度为O(n)