折半查找
Binary Search
- . 也叫二分查找
- 过程 Procedure
-
. 将表看作一个查找区间,用low、high,mid = (low + high)/2 来标识查找区间的下界、上界和中间位置. mid是整除的结果;如果给定值和mid对应的值相等,查找成功. 如果给定值小于中间记录值,则在前半段继续查找,high = mid - 1,low不变. 如果给定值大于中间记录值,则在后半段继续查找,low = mid + 1,high不变. 如果比较到最后,low > high ,查找结束. 查找范围每次都缩小一半,所以查找效率高
查找过程 0 ... ... (0+n)/2 ... ... n data ... ... data ... ... data ↑ ↑ ↑ low mid high - 伪代码 Pseudo Code
-
. 封装为函数:int binarySearch(int low,int high,int key)
#include <stdio.h> int main () { int a[] = {0, 5, 13, 19, 22, 41, 55, 68, 72, 81, 98}; int low = 0, high, mid, index = -1; high = sizeof(a)/sizeof(a[0]); int target = 12; while(low <= high){ mid = (low + high)/2; if(a[mid] == target){ index = mid; break; }else if(a[mid] < target){ low = mid + 1; }else{ high = mid - 1; } } if(index == -1){ printf("Not Found\n"); }else{ printf("Found at %d\n",index); } return 0; }
- 性能分析 Analysis
-
. 优点:查找效率高,特别适合大数据量. 缺点:表必须是顺序存储的有序表. 不适用于数据元素经常变化的表. 时间复杂度 O(log2N). 更多信息,请查看 Binary Sort、懒猫老师
- 查找21的过程
-
二分查找 0 1 2 3 4 5 6 7 8 9 10 5 13 19 21 37 56 64 75 80 88 92 第一次查找:low = 0, high = 10, mid = (low + high)/2 = 5, 对应的数据为56 > 21, 说明21在前面一半第二次查找:low = 0, high = 4, mid = (low + high)/2 = 2, 对应的数据为19 < 21, 说明21在后面一半第三次查找:low = 3, high = 4, mid = (low + high)/2 = 3, 对应的数据为21 = 21, 查找成功 - 查找21的过程
-
第1次查找:low = 0;high = 10mid = (low + high)/2 = (0 + 10)/2 = 551 > 21,目标在前半段,∴ low = 0,high = mid – 1 = 4
第1次查找 0 1 2 3 4 5 6 7 8 9 10 6 10 20 21 49 51 69 79 82 88 94 low mid high 第2次查找:low = 0;high = 4mid = (low + high)/2 = (0 + 4)/2 = 220< 21,目标在后半段,∴ low=mid + 1=3,high=4第2次查找 0 1 2 3 4 5 6 7 8 9 10 6 10 20 21 49 51 69 79 82 88 94 low mid high 第3次查找:low = 3;high = 4mid = (low + high)/2 = (3 + 4)/2 = 321== 21,查找结束第3次查找 0 1 2 3 4 5 6 7 8 9 10 6 10 20 21 49 51 69 79 82 88 94 low|mid high - 从0,5,13,19,22,41,55,68,72,81,98中查找68的比较次数为( )。
-
2345
-
4次
- 从0,5,13,19,22,41,55,68,72,81,98中查找12的比较关键字分别是( )。
-
41,13,0,5
- 采用折半查找法对长度为12的有序表进行查找,在等概率情况下查找成功所需的平均比较次数为( )。
-
35/1237/1239/1243/1237/12;[构建完全二叉树]1次查找成功:52次查找成功:2、83次查找成功:0、3、6、103次查找成功:1、4、7、9、11合计 = 1 + 2*2 + 3*4 + 4*5 = 37平均 = 37/12
- 给定折半查找有序表(4, 6, 10, 12, 20, 30, 50, 70, 88, 100, 120)。若查找表中元素58,则算法将依次与表中哪些元素比较大小才以失败结束?
-
0 1 2 3 4 5 6 7 8 9 10 4 6 10 12 20 30 50 70 88 100 120 第1次 low=0, high=10, mid=(low+high)/2=5, loc(5)=30<58, 58应在后半段第2次 low=6, high=10, mid=(low+high)/2=8, loc(8)=88>58, 58应在前半段第3次 low=6, high=7, mid=(low+high)/2=6, loc(6)=50<58, 58应在后半段第4次 low=7, high=7, mid=(low+high)/2=7, loc(7)=70!=58, 58查找失败结论:分别与:30、88、50、70比较 - 给定折半查找有序表如下表。若查找表中元素83,能否查找成功?如果成功,查找几次?分别与哪些记录比较?如果失败,分别与哪些记录比较?
-
0 1 2 3 4 5 6 7 8 9 10 6 10 20 21 49 51 69 79 82 88 94 第1次 low=0, high=10, mid=(low+high)/2=5, loc(5)=51<83, 83应在后半段第2次 low=6, high=10, mid=(low+high)/2=8, loc(8)=82<83, 83应在后半段第3次 low=9, high=10, mid=(low+high)/2=9, loc(9)=88>83, 83应在前半段,应该比9小;但是现在low已经是9了,出现异常,查找83失败结论:分别与:51、82、88比较