- 该合辑为笔者自b站自学的“C++数据结构与算法”课程学习记录,旨在将重要的学习要点、思考内容与部分代码进行记录,以便后续自行翻看,亦可给其他读者带来一些参考
- 内容基于笔者自身的理解或感悟,可能存在不妥当或是错误之处
- 系统环境:Win10,Visual Studio 2019
- 文中图片参考东北大学“数据结构与算法设计” (2020) 线上课程讲义
目录
Static / dynamic search table
顺序查找
安插哨兵倒序查找,不用考虑越界的问题,其算法简单,不需要源数据排序,但效率较低O(n)
二分查找
元素必须有序存放,可以达到O(logn)
二叉搜索树
查找性能时好时坏
- 普通二叉搜索树的查找性能和树的形态有关,其性能从 O(logn) ~ O(n) 阶不等,如果是退化到线性的二叉树,则搜索性能最为差劲,较为理想的情况是满二叉树或完全二叉树
- 因此,可以在元素插入时进行一定的人为控制与干预,来调整树的形态,由此引入AVL树...
AVL树
高度平衡的二叉搜索树
对于树的形态,我肯可以形容为“完美”,“挺不错”,和“很差”等等,想要追求完美,就要付出很大的代价,在元素插入时,我们要付出很大的时间精力来对树的形态进行调整,极端情况下甚至树的绝大多数元素都要因为追求形态完美而调整位置。
因此,我们想要花一般的精力,做到“近似于完美”,也就是“挺不错”的树的形态。AVL树允许不完美,允许子树的高度有差异,因此在元素插入时我们要进行的调整要少一些
引入平衡因子概念,其为一节点左右子树高度差值的绝对值,AVL树允许此值等于1或0,若一个元素插入会导致某个节点的平衡因子等于2,则要进行元素位置的调整,具体调整的方法视情况而定,一共有四种情况:
- 外节点:左子树 - 左子树 插入,一次旋转调整
- 外节点:右子树 - 右子树 插入,一次旋转调整
- 内节点:左子树 - 右子树 插入,两次旋转调整
- 内节点:右子树 - 左子树 插入,两次旋转调整
具体旋转方法在此处不再引申,总之是回溯到最近的出问题的祖先节点进行问题的解决,使整棵树仍是一颗AVL树
若是想删除元素,则进行的操作更为复杂,我们需要回溯该节点的所有祖先节点,保证删除该节点后树的平衡因子仍达到要求
B - 树
减少磁盘读取
一般的搜索树存在一个问题,当元素的数量增多时,树的高度也会增多,带来查找效率的下降的同时,对于磁盘访问的次数也会增多,传统机械磁盘的读取效率远慢于内存,故利用B - 树来尝试解决上述问题
B - 树可以看做是一种 m - way tree (多路树),其树的度可以大于2,m通常为奇数
通过关键字来划分叶节点取值的范围,最大关键字的个数为m-1,B - 树可以在很大程度上减少数的高度,提高搜索效率
The End