TIPS:折半查找是很重要的算法,不管是大题还是小题,考查频率都很高。
TIPS:由于分块查找一般都是在选择题中进行考查,很少考查代码,关注算法思想即可。分块查找的查找效率ASL,一般只讨论查找成功的ASL情况,不考虑查找失败的情况(因为比较复杂,考试也不太会考)。
折半查找/二分查找:仅适用于有序的顺序表。(顺序表拥有随机访问的特性,而链表没有)
算法思想:
1,设置关键字key;设置两个初始指针low=0,high=LENGTH-1,mid=(low+high)/2并向下取整;
2,如果key>mid,那么有:low=mid+1;如果key<mid,那么有:high=mid-1;
3,如果此时一直对比,直到low>high,查找失败;
代码实现:
20230522,暂不关注;待后期二轮三轮关注代码方面。
查找效率分析:
参考顺序查找关于有序表的判定树:如果树中有N个结点,那么就会有N+1个查找失败的空结点(该空结点指针为null,不参与计算)。
☆折半查找——查找判定树的构造:
如果当前low和high之间有奇数个元素,则mid分隔后,左右两部分元素个数相等;
如果当前low和high之间有偶数个元素,则mid分割后,左半部分比右半部分少一个元素;(因为mid=(low+high)/2,向下取整!!)
基于上述两点可知:对任何一个结点而言,必然有——右子树结点数-左子树结点数=0 or 1;
( TIPS:如果mid=(low+high)/2向上取整,那么左子树结点数-右子树结点数=0 or 1;)
具体案例——具有四个元素的查找表对应的折半查找判定树:
具有五个元素的查找表对应的折半查找判定树:
具有六个元素的查找表对应的折半查找判定树:以此类推......
总结:折半查找判定树一定是一颗二叉平衡排序树,且只有最下面一层是不满的,因此,元素个数为N个时,失败结点为N+1个(等于成功结点的空链域数量),树高h=。
☆查找成功/失败的平均查找长度,必然是小于等于树高h的,那么有:。
分块查找/索引顺序查找:分块的索引表查找,以及每个分块的查找相结合。
分块查找特点:块内无序,块间有序。
分块查找——算法过程:
1,在索引表中确定待查找记录所属的分块(可用顺序查找/折半查找);
2,块内遍历元素
分块查找——————顺序查找索引表
分块查找——查找成功的案例演示1,如图所示:
分块查找——查找失败的案例演示,如图所示:
分块查找——————折半查找索引表
分块查找——折半查找索引表,且查找失败的案例演示,如图所示:
☆若索引表不包含目标关键字,则折半查找索引表最终停留在low>high,要在Low所指的分块中进行查找。
要在Low所指的分块中进行查找的原因????
答:最终low左边一定小于目标关键字,high右边一定大于目标关键字。而分块存储的索引表中,保存的是各个分块的最大关键字。
分块查找——折半查找索引表,且查找失败的案例演示2,如图所示:
该情况low指针所指地方直接超出了索引表的范围,所以可直接返回查找失败。
分块查找——查找效率分析()
下述案例是索引表为顺序查找的,如图所示:
考试会考的一个场景:假设长度为N的查找表被均匀地分为b块,每块S个元素;在这种情况下,分块查找的平均成功查找长度为:
令Li(index,索引查找),Ls(块内查找),ASL成功=Li+Ls;其中N=SB,则B=N/S;
若此时N=10000,那么ASL最小值min=101;
;该情况不重要,可不用太关注。
拓展:若折半查找的查找表是动态查找表,有没有更好的实现方式?
答:折半查找分为索引表和索引表内各个块表,块表中可以用指针方式进行链接,也就是链表进行链式存储,这样可以很容易的进行动态增删。