###1、折半查找 折半查找(Binary Search)又称为二分查找。 注意 折半查找方法要求查找表的数据是线性结构保存,而且还要求查找表中的数据是按关键字由小到大有序排列。 ####折半查找的具体过程 假设有n个元素的查找表,首先计算位于查找表中间位置元素的序号m(m=n/2),取s[m]的关键字与给定值key进行比较。比较结果有3种可能 (1)若s[m]=key,表示查找成功。 (2)若s[m]>key,表示关键字key只可能在查找表的前半部分(因查找表中的数据是按从小到大的顺序排 列),则在前半部分继续进行折半查找。 (3)若s[m]<key,表示关键字key只可能在查找表的后半部分,则在后半部分继续进行折半查找。 技巧 从上面的过程可看出,折半查找是一种递归过程。每折半查找一次,可以使查找范围缩小一半,当查找范 围缩小到只剩下一个元素,而该元素仍与关键字不相等,则说明查找失败。 在最坏的状况下,折半查找所需的比较次数为O(nlog 2 n),其查找效率比顺序查找法要快不少 例如,有如下数据: 6,12,28,37,54,65,69,83,90,92 若要查找关键字37,则查找过程以下图1:数组
从上图1的查找过程可看出,经过4次比较,可找到关键字37所在的位置。再例如,若要查找关键字66,其查找过程以下图2:测试
从上图2的过程可看出,经过4次比较,当查找范围缩小到只剩一个元素,仍没有找到指定关键字,说明查找失败。code
###2、折半查找实现 ####折半查找法排序
/** *折半查找法(非递归) * */ int BinarySearch1(int s[], int n, int key) { int low, high, mid; low = 0; high = n-1; while (low <= high) { //查找结束条件,即至少包含一个元素 mid = (low + high)/2; //计算中间位置 if (s[mid] == key) //若是中间位置与关键字相同 return mid; //返回序号 else if (s[mid] > key) //中间元素大于关键字,关键字在左边 high = mid - 1; //从新定义high else //中间元素大于关键字,关键字在右边 low = mid + 1; //从新定义low } return -1; } /** *折半查找法(递归) * */ int BinarySearch2(int s[], int low, int high, int key) { int mid; if (low <= high) { //查找结束条件,即至少包含一个元素 mid = (low + high)/2; //计算中间位置 if (s[mid] == key) //若是中间位置与关键字相同 return mid; //返回序号 else if (s[mid] > key) //中间元素大于关键字,关键字在左边 return BinarySearch2(s, low, mid-1, key); else return BinarySearch2(s, mid+1, high, key); } else return -1; }
####折半查找法测试递归
#include <stdio.h> #include "BinarySearch.c" #define ARRAYLEN 10 int main() { int key, i, pos; int source[ARRAYLEN]={6, 12, 28, 37, 54, 65, 69, 83, 90, 92}; /*折半查找,非递归*/ printf("请输入查找关键字:"); scanf("%d", &key); pos = BinarySearch1(source, ARRAYLEN, key); printf("原数据:"); for (i=0; i< ARRAYLEN; i++) printf("%d ", source[i]); printf("\n"); if (pos >= 0) printf("查找成功,关键字%d位于数组的第%d个位置\n", key, pos); else printf("查找失败,关键字%d不在数组中\n", key); /*折半查找,递归*/ printf("请输入查找关键字:"); scanf("%d", &key); pos = BinarySearch2(source, 0, ARRAYLEN-1, key); printf("原数据:"); for (i=0; i< ARRAYLEN; i++) printf("%d ", source[i]); printf("\n"); if (pos >= 0) printf("查找成功,关键字%d位于数组的第%d个位置\n", key, pos); else printf("查找失败,关键字%d不在数组中\n", key); }
###3、折半查找特色 ❑优势:查找速度快,最多查找次数为O(nlog 2 n)图片
❑缺点:对查找表中的数据有顺序要求,在进行查找前首先进行排序。若是须要将查找不成功的关键字数据添加到查找表中,则须要对查找表中的已有数据进行大量的移动操做。it