二分查找又称折半查找、二叉查找,它是一种效率较高的查找方法。
问题描述
给定一已排好序的n个元素a[0 : n-1],现要在这n个元素中找出一特定元素x。
算法 思想
首先,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大 于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成 功。
算法实现
在VC6.0环境使用C++编写算法演示程序 代码 如下:
- #include <iostream>
- using namespace std;
- int binSrch(int *, int, int, int);
- void main()
- {
- cout << "此处程序入口,用于测试算法:/n";
- cout << "Welcome to use! Test begin .../n";
- int a[] = {-15, -6, 0, 7, 9, 23, 54, 82, 101, 112, 125, 131, 142, 151};
- int length = 14;
- cout << "数组为:";
- for (int i = 0; i < length; i++)
- {
- cout << a << " ";
- }
- cout << "/n";
- cout << "使用递归二分查找151结果为(下标从0开始):";
- cout << binSrch(a, 0, length - 1, 151);
- cout << "/n";
- cout << "使用循环二分查找151结果为(下标从0开始):";
- cout << binSrch(a, 0, length - 1, 151);
- cout << "/n";
- }
- int binSrch(int a[], int i, int l, int x)
- /*
- 二分查找:递归实现在数组a[i : l]之间查找x,i从0到n-1,
- a[]为非降序数组。如果找到将返回元素的下标,如果未找到则返回-1
- */
- {
- if (l == i) //只有一个元素,不可分,可以直接解题
- {
- if (x == a)
- return i;
- else
- return -1;
- }
- else //运用分治法将问题划分为小规模的子问题处理
- {
- int mid = (l + i) / 2;
- if (x == a[mid])
- return mid;
- else
- if (x < a[mid])
- return binSrch(a, i, mid - 1, x);
- else
- return binSrch(a, mid + 1, l, x);
- }
- }
- int binSearch(int a[], int n, int x)
- /*
- 使用非递归方法实现上述二分查找
- */
- {
- int low = 1, high = n;
- while (low <= high)
- {
- int mid = (low + high) / 2;
- if (x < a[mid])
- high = mid -1;
- else if (x > a[mid])
- low = mid + 1;
- else
- return mid;
- }
- return -1;
- }
运行结果
此处程序入口,用于测试算法:
Welcome to use! Test begin ...
数组为:-15 -6 0 7 9 23 54 82 101 112 125 131 142 151
使用递归二分查找151结果为(下标从0开始):13
使用循环二分查找151结果为(下标从0开始):13
算法分析
优点是折半查找法的优点是比较次数少,查找速度快,平均性能好;
缺点是要求待查表为有序表,且插入删除困难。
因此,折半查找方法适用于不经常变动而查找频繁的有序列表
算法复杂度:假设其数组长度为n,其算法复杂度为o(log(n))
参考文献:
(美)霍罗威茨(Horowitz, E.)等著, 冯博琴等译. 计算机算法: C++版. 北京: 机械工业出版社, 2006. 1.(Ellis Horowitz, Sartaj Sahni, Sanguthevar Rajasekaran. Computer Algorithms/C++.)
王晓东编著. 计算机算法设计与分析(第2版). 北京:电子工业出版社, 2004. 7.