数据结构
第一部分 线性表
- n个数据元素的有限序列
- 数组实现:优点在于可以通过下标来访问或者修改元素,比较高效,主要缺点在于插入和删除的花费开销较大
- 链表实现:物理存储单元上非连续、非顺序的存储结构
第二部分 栈与队列
1.栈:Last In First Out

2.队列:先进先出

第三部分 树
一、二叉树
- 二叉树
- 遍历方法:先序遍历、中序遍历、后序遍历(可用递归实现)
-
二叉查找树
- 若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
- 若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
- 左、右子树也分别为二叉排序树;
- 没有键值相等的结点。
-
二叉查找树的实现
-
二叉查找树的删除实现
要在二叉查找树中删除一个元素,首先需要定位包含该元素的节点,以及它的父节点。假设current指向二叉查找树中包含该元素的节点,而parent指向current节点的父节点,current节点可能是parent节点的左孩子,也可能是右孩子。这里需要考虑两种情况:
- current节点没有左孩子,那么只需要将patent节点和current节点的右孩子相连。
- current节点有一个左孩子,假设rightMost指向包含current节点的左子树中最大元素的节点,而parentOfRightMost指向rightMost节点的父节点。那么先使用rightMost节点中的元素值替换current节点中的元素值,将parentOfRightMost节点和rightMost节点的左孩子相连,然后删除rightMost节点。
二、平衡二叉树
- 它或者是一棵空树,或者是具有下列性质的二叉树----它的左子树和右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1
- AVL树是最先发明的自平衡二叉查找树算法。在AVL中任何节点的两个儿子子树的高度最大差别为1,所以它也被称为高度平衡树,n个结点的AVL树最大深度约1.44log2n。查找、插入和删除在平均和最坏情况下都是O(log n)。增加和删除可能需要通过一次或多次树旋转来重新平衡这个树。
三、红黑树
-
红黑树放弃了追求完全平衡,追求大致平衡,在与平衡二叉树的时间复杂度相差不大的情况下,保证每次插入最多只需要三次旋转就能达到平衡,实现起来也更为简单。
-
平衡二叉树追求绝对平衡,条件比较苛刻,实现起来比较麻烦,每次插入新节点之后需要旋转的次数不能预知。
-
性质:这些性质保证了根到叶子的路径不会超过最短路径的两倍
- 节点是红色或黑色。
- 根是黑色。
- 所有叶子都是黑色。
- 不能有两个连续的红色节点
- 所有简单路径都包含相同数目的黑色节点
-
旋转操作:左旋、右旋
(1)插入:插入红色节点,如果插入的节点是黑色,那么这个节点所在路径比其他路径多出一个黑色节点。仅可能会出现两个连续的红色节点的情况。这种情况下,通过变色和旋转进行调整即可
- 情况一:插入的新节点 N 是红黑树的根节点,把节点 N 的颜色由红色变为黑色

- 情况二:N 的父节点是黑色,无需调整

- 情况三:N 的父节点是红色,叔叔节点 U 也是红色,性质4被打破。先将 P 和 U 的颜色染成黑色,再将 G 的颜色染成红色。 G 被染成红色后,可能会和它的父节点形成连续的红色节点。

- 情况四:N 的父节点为红色,叔叔节点为黑色。节点 N 是 P 的右孩子,且节点 P 是 G 的左孩子。先对节点 P 进行左旋,调整 N 与 P 的位置。接下来按照情况五进行处理,以恢复性质4。

- 情况四是由以 N 为根节点的子树中插入了新节点,经过调整后,导致 N 被变为红色,进而导致了情况四的出现。

- 情况五:N 的父节点为红色,叔叔节点为黑色。N 是 P 的左孩子,且节点 P 是 G 的左孩子。对 G 进行右旋,调整 P 和 G 的位置,并互换颜色。性质4被恢复,同时也未破坏性质5。

- 插入总结:这情况三四五的区别在于叔叔节点的颜色,如果叔叔节点为红色,直接变色即可。如果叔叔节点为黑色,则需要先旋转,再交换颜色。

(2)删除“找前驱或后继,转化为至多一个孩子节点的删除;当删除的节点是红色时,直接拿其孩子节点补空位即可;当删除的节点是黑色时,如果该节点的孩子为红色,直接拿孩子节点替换被删除的节点,并将孩子节点染成黑色,即可恢复性质5。(双黑节点)但如果孩子节点为黑色,分为6种情况:假设最终被删除的节点为X,其孩子节点为N,X的兄弟节点为S,S的左节点为 SL,右节点为 SR。接下来讨论是建立在节点 X 被删除,节点 N 替换X
-
情况一:N 是新的根。
-
情况二:S 为红色,其他节点为黑色。这种情况下可以对 N 的父节点进行左旋操作,然后互换 P 与 S 颜色。性质5仍不满足,按照情况四、五、六进行调整。
-
情况三:N 的父节点,兄弟节点 S 和 S 的孩子节点均为黑色。把 S 染成红色,所有经过 S 的路径比之前少了一个黑色节点,这样经过 N 的路径和经过 S 的路径黑色节点数量一致了。但经过 P 的路径比不经过 P 的路径少一个黑色节点,此时需要从情况一开始对 P 进行平衡处理。
-
情况四:N 的父节点是红色,S 和 S 孩子为黑色。这种情况比较简单,我们只需交换 P 和 S 颜色即可。这样所有通过 N 的路径上增加了一个黑色节点,所有通过 S 的节点的路径必然也通过 P 节点,由于 P 与 S 只是互换颜色,并不影响这些路径。
-
情况五:S 为黑色,S 的左孩子为红色,右孩子为黑色。N 的父节点颜色可红可黑,且 N 是 P 左孩子。对 S 进行右旋操作,并互换 S 和 SL 的颜色。
此时,所有路径上的黑色数量仍然相等,N 兄弟节点的由 S 变为了 SL,而 SL 的右孩子变为红色。接下来我们到情况六继续分析。 -
情况六:S 为黑色,S 的右孩子为红色。N 的父节点颜色可红可黑,且 N 是其父节点左孩子。这种情况下,我们对 P 进行左旋操作,并互换 P 和 S 的颜色,并将 SR 变为黑色。因为 P 变为黑色,所以经过 N 的路径多了一个黑色节点,经过 N 的路径上的黑色节点与删除前的数量一致。对于不经过 N 的路径,则有以下两种情况:
该路径经过 N 新的兄弟节点 SL ,那它之前必然经过 S 和 P。而 S 和 P 现在只是交换颜色,对于经过 SL 的路径不影响。
该路径经过 N 新的叔叔节点 SR,那它之前必然经过 P、 S 和 SR,而现在它只经过 S 和 SR。在对 P 进行左旋,并与 S 换色后,经过 SR 的路径少了一个黑色节点,性质5被打破。另外,由于 S 的颜色可红可黑,如果 S 是红色的话,会与 SR 形成连续的红色节点,打破性质4。此时仅需将 SR 由红色变为黑色即可同时恢复性质4和性质5 -
删除总结:

四、B树(m阶)
- 规则:
- 排序方式:所有节点关键字是按递增次序排列,并遵循左小右大原则;
- 子节点数:非叶节点的子节点数>1,且<=M ,且M>=2,空树除外;
- 关键字数:枝节点的关键字数量大于等于ceil(m/2)-1个且小于等于M-1个(注:ceil()是个朝正无穷方向取整的函数 如ceil(1.1)结果为2);
- 所有叶子节点均在同一层、叶子节点除了包含了关键字和关键字记录的指针外也有指向其子节点的指针只不过其指针地址都为null对应下图最后一层节点的空格子;
- 插入操作:节点关键字数>m-1时,将中间元素提取到父节点,左右单独构成结点。
- 删除操作:节点关键字数<ceil(m/2)-1时,先从子节点提取,若没有,从父节点取。(可能需要递归:被提取的节点也需要再次提取)

五、B+树
-
概念:B+树是B树的一个升级版,相对于B树来说B+树更充分的利用了节点的空间,让查询速度更加稳定,其速度完全接近于二分法查找。
-
规则:
- B+跟B树不同B+树的非叶子节点不保存关键字记录的指针,只进行数据索引,这样使得B+树每个非叶子节点所能保存的关键字大大增加;
- B+树叶子节点保存了父节点的所有关键字记录的指针,所有数据地址必须要到叶子节点才能获取到。所以每次数据查询的次数都一样;
- B+树叶子节点的关键字从小到大有序排列,左边结尾数据都会保存右边节点开始数据的指针。
- 非叶子节点的子节点数=关键字数
-
插入操作

-
删除操作


-
为什么说B+树比B树更适合数据库索引?
- B+树的磁盘读写代价更低:B+树的内部结点并没有指向关键字具体信息的指针。因此其内部结点相对B 树更小。如果把所有同一内部结点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就越多。相对来说IO读写次数也就降低了;
- B+树查询效率更加稳定:由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当
- B+树便于范围查询(最重要的原因,范围查找是数据库的常态):B树在提高了IO性能的同时并没有解决元素遍历的我效率低下的问题,正是为了解决这个问题,B+树应用而生。B+树只需要去遍历叶子节点就可以实现整棵树的遍历。而且在数据库中基于范围的查询是非常频繁的,而B树不支持这样的操作或者说效率太低;(B树的范围查找用的是中序遍历,而B+树用的是在链表上遍历;)
六、B*树
- 规则:B*树是B+树的变种,相对于B+树他们的不同之处如下
- 关键字个数限制:B+树初始化的关键字初始化个数是cei(m/2),b*树的初始化个数为 cei(2/3×m)
- B+树节点满时就会分裂,而B*树节点满时会检查兄弟节点是否满(因为每个节点都有指向兄弟的指针),如果兄弟节点未满则向兄弟节点转移关键字,如果兄弟节点已满,则从当前节点和兄弟节点各拿出1/3的数据创建一个新的节点出来;

第四部分 图
- 图形结构中,节点之间的关系可以是任意的,图中任意两个数据元素之间都可能相关

浙公网安备 33010602011771号