文字描述
以有序表表示静态查找表时,可用折半查找算法查找指定元素。
折半查找过程是以处于区间中间位置记录的关键字和给定值比较,若相等,则查找成功,若不等,则缩小范围,直至新的区间中间位置记录的关键字等于给定值或者查找区间的大小小于零时(表明查找不成功)为止。
示意图
算法分析
折半查找过程可以用一颗二叉判定树来表示,而具有n个结点的判定树的深度为[log2n]+1,所以折半查找法在查找成功和不成功时,与给定值进行比较的关键字个数都不会超过[log2n]+1. 现讨论折半查找算法的平均查找长度。
为讨论方便,假设有序表长度为n=2h-1,则描述折半查找的判定树是深度为h的满二叉树。假设每个记录的查找概率相等Pi = 1/n, 则折半查找查找成功的平均查找长度
当n足够大时,平均查找长度约为log2(n+1)-1 可见,折半查找的效率比顺序查找要高,但是折半查找只适用于有序表,且限于顺序存储结构,对线性链表无法有效地进行折半查找。
代码实现
1 /*
2 ./a.out 5 13 19 21 37 56 64 75 80 88 92
3 */
4 #include <stdio.h>
5 #include <stdlib.h>
6
7 #define EQ(a, b) ((a) == (b))
8 #define LT(a, b) ((a) < (b))
9 #define LQ(a, b) ((a) <= (b))
10 #define MAX_SIZE 50
11 #define DEBUG
12
13 typedef int KeyType;
14 typedef char InfoType;
15 /*数据元素类型定义*/
16 typedef struct{
17 //关键字域
18 KeyType key;
19 //其他域
20 InfoType otherinfo;
21 }ElemType;
22 /*静态查找表的顺序存储结构*/
23 typedef struct{
24 //数据元素存储空间基址,建表时按实际长度分配,0号单元留空
25 ElemType *elem;
26 //表长度
27 int length;
28 }SSTable;
29
30 /*折半查找算法
31 *
32 *顺序表中的元素应该按照由小到大顺序排列.
33 *
34 *在顺序表ST中顺序查找其关键字等于key的数据元素。
35 *若找到,则函数值为该元素在表中的位置,否则为0
36 */
37 int Search_Bin(SSTable ST, KeyType key){
38 //置区间初值
39 int low = 1;
40 int high = ST.length;
41 int mid = (low+high)/2;
42 while(low<=high){
43 mid = (low+high)/2;
44 if(EQ(ST.elem[mid].key, key)){
45 //找到待查元素
46 return mid;
47 }else if(LT(ST.elem[mid].key, key)){
48 //继续在后半区间查找
49 low = mid+1;
50 }else{
51 //继续在前半区间查找
52 high = mid-1;
53 }
54 }
55 return 0;
56 }
57
58 //顺序打印顺序表中的数据元素
59 void print_Seq(SSTable ST){
60 int i = 0;
61 for(i=1; i<= ST.length; i++){
62 printf("[%d]=%d/%c; ", i, ST.elem[i].key, ST.elem[i].otherinfo);
63 }
64 printf("\n");
65 }
66
67 int main(int argc, char *argv[])
68 {
69 int i = 0, loc = 0, key=0;
70 ElemType arr[MAX_SIZE+1] = {0};
71 for(i=1; i<argc; i++){
72 arr[i].key = atoi(argv[i]);
73 arr[i].otherinfo = 'a'+i-1;
74 }
75 SSTable ST;
76 ST.length = i-1;
77 ST.elem = arr;
78 #ifdef DEBUG
79 printf("输入了数据:");
80 print_Seq(ST);
81 #endif
82 while(1){
83 printf("输入待查找的key值(负值表示结束):");
84 scanf("%d", &key);
85 if(key < 0)
86 break;
87 loc = Search_Bin(ST, key);
88 printf("key值为%d的位置在%d\n", key, loc);
89 }
90 return 0;
91 }
折半查找(有序表)
运行