书籍被摆放在书架之中,书架被一个个标好了序号,整齐的排列在一起。走进这图书馆之中,寻找着心怡的书籍,当然可以从头走到尾一个个找下去,可是也许有其他更好的方法呢?
这是来自线性表(顺序表、链表)的简单方法,基于其下标和顺序性,查找着键值为给定值的元素或结点
1.二分查找
或许书籍已经按照价格大小排列整齐,而预算有限,书籍太多,找到一本价格合适的书籍,从头走到尾或许不太合适,直接走到书架的中间部分,比较书籍的价格和自己的预算价格,就能知道自己想要的价格区间该去哪里找了
1.算法1-1
功能:给定具有n个元素的顺序表sl,确定是否存在键值为k的元素
算法步骤
(1)定义两个整型变量left和right,分别表示当前子区间的下标区间的左端点和右端点,初始值为0和n-1
(2)如果left>right,当前子表为空,查找失败,结束;否则计算当前子表下标的中间点mid=(left+right)/2,并比较sl[mid]与k的大小,分为以下3种情况:
- 如果sl[mid]=k,查找成功,结束
- 如果sl[mid]>k,则k只能出现在左半区间,令right=mid-1,进入第(2)步
- 如果sl[mid]<k,则k只能出现在右半区间,令left=mid+1,进入第(2)步
2.示例与代码
给定有序顺序表sl={3,4,6,8,10,12,14,16,18,20}中查找键值为14的元素下标
#include<iostream>
#include<vector>
using namespace std;
//二分查找,查找顺序表sl的下标区间中是否存在值为k的元素,存在返回下标,否则返回-1
int binary_search(vector<int>sl, int left, int right, int k) {
int mid;
if (left > right)return -1;//查找失败
mid = (right + left) >> 1;//下标区间的中间位置,等价于(right+left)/2
if (sl[mid] == k)return mid;//查找成功
else if (sl[mid]>k)return binary_search(sl, left, mid - 1, k);//转到左半区间查找
else return binary_search(sl, mid + 1, right, k);//转到右半区间查找
}
//二分查找的非递归实现,查找顺序表sl的下标区间中是否存在值为k的元素,存在返回下标,否则返回-1
int binary_search_no(vector<int>sl, int k) {
int left = 0, right = sl.size() - 1, mid;
while (left <= right) {
mid = (right + left) >> 1;//下标区间的中间位置,等价于(right+left)/2
if (sl[mid] == k)return mid;//查找成功
else if (sl[mid]>