顺序查找

哨兵

将查找表的第一个元素设置为待查找的元素,将关键字匹配和数组越界的比较合一,可以减少比较次数。

  1. /**
  2. * 返回 0,说明遇到哨兵,查找失败
  3. * 返回 >0,查找成功
  4. */
  5. function(SearchTable table, Key key) {
  6. table[0] = key;
  7. // 从后往前找
  8. for (i = table.size(); table[i] != key; --i);
  9. return i;
  10. }

有序线性表的查找

有序线性表的查找过程对应的「判定树」为:
image.png

其中:

  • 「圆形节点」表示线性表中存在的元素
  • 「矩形节点」表示失败节点,可以报告错误信息

注:有序线性表和无序线性表,如果查找成功,两者的平均查找次数是相同的;如果查找不成功,有序线性表的平均查找次数更少

折半查找

只能用于有序顺序表

平均查找长度为(记一下这个结论):顺序查找和折半查找 - 图2

折半查找的过程对应的「判定树」为:(左右子树的节点数量不超过 1,仅考虑圆形节点)
image.png

注:区别「折半查找」和「二叉排序树」的查找。「二叉排序树」的树形可能不是平衡的,极端情况是「单支树」;而「折半查找」对应的判定树是平衡的

折半查找的判定树,在画的时候需要有一致的「取整方法」:
image.png

分块查找

为什么要有分块查找

折半查找已经非常高效了,为什么还要有分块查找?
因为折半查找是一个「静态」的结构,增删数据时开销较大;
「分块查找」的结构是一个折中,增删数据时开销不会很大,查找速度也不会很慢。

分块查找

结合了顺序查找和折半查找,做到了块间有序,块内无序。块间可以使用折半查找,块内可以使用顺序查找。
分块查找.PNG

平均查找长度

查找表总长度为 顺序查找和折半查找 - 图6,均匀地分为 顺序查找和折半查找 - 图7 块,每块大小为 顺序查找和折半查找 - 图8

如果索引部分使用顺序查找,则 顺序查找和折半查找 - 图9,当 顺序查找和折半查找 - 图10 时平均查找次数最小(均值不等式)

如果索引部分使用折半查找,则 顺序查找和折半查找 - 图11