在一个无序的数据序列中查找某一个数值,我们只能遍历该序列的每一个数值,并与要查找的数值比较。时间复杂度为O(N)。
在有序排序(假定从小到大)的数据序列中查找某一个数值,没有必要遍历每一个数值。我们可以用二分查找。
在有序排序(假定从小到大)的数据序列中查找某一个数值,没有必要遍历每一个数值。我们可以用二分查找。
基本思路是:
将序列的中间值和val比较,如果data[mid]大于val,则说明序列中在data[mid]右边的数据都大于val。所以我们只能在data[mid]的左边查找。这样我们就将比较范围缩小了一半。每次比较我们都可以将范围缩小一半。该算法的时间复杂度为O(logN)。
源代码:
/*************************************************************************
> File Name: bin_search.cpp
> Author:
> Mail:
> Created Time: 2016年01月06日 星期三 13时09分47秒
************************************************************************/
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
void input_data(vector<int> & data)
{
cout << "输入数据:";
int tmp;
while(cin >> tmp && tmp != -10000){
data.push_back(tmp);
}
}
void output_data(vector<int> & data)
{
cout << "输入的数据: ";
for (vector<int>::iterator it = data.begin(); it != data.end(); ++it){
cout << *it << " ";
}
cout << endl;
}
int bin_search(vector<int> & data, int val)
{
int low = 0, high = data.size()-1;
int mid;
while(low <= high){
mid = (low + high)/2;
if(data[mid] < val)
low = mid + 1;
else if(data[mid] > val)
high = mid - 1;
else
return mid;
}
return data.size();
}
int main()
{
vector<int> data;
input_data(data);
//排序
cin.get();
sort(data.begin(), data.end());
//输入要查找的数据
output_data(data);
int val;
cout << "输入要查找的数据: ";
cin >> val;
int index = bin_search(data, val);
if(index == data.size()){
cout << "index = " << index << ", data doesn't have " << val << endl;
return 0;
}
cout << "index = " << index << ", data[index] = " << data[index] << endl;
return 0;
}
下面是二分查找的递归实现:
/*************************************************************************
> File Name: binarySearch.cpp
> Author:
> Mail:
> Created Time: 2016年04月16日 星期六 19时47分10秒
************************************************************************/
#include <iostream>
#include <time.h>
#include <stdlib.h>
#include <vector>
#include <algorithm>
using namespace std;
//二分查找
int binarySearch(vector<int> & v, int first, int last, int value)
{
int half = (first+last)/2;
if(v[half] == value)
return half;
else if(v[half] < value)
return binarySearch(v, half, last, value);
else
return binarySearch(v, 0, half, value);
}
//主函数
int main()
{
srand(unsigned(time(0)));
vector<int> v;
for(int i = 0; i < 10; ++i)
v.push_back(rand()%10);
sort(v.begin(), v.end());//排序
cout << "v: ";
for(int i = 0; i < 10; ++i)
cout << v[i] << " ";
cout << endl;
int val = v[rand()%10];
int index = binarySearch(v, 0, v.size()-1, val);
cout << val << " index is " << index << endl;
return 0;
}
//二分查找
int binarySearch(vector<int> & v, int first, int last, int value)
{
if(first < last)
return;//没有找到则返回,之前忘了找不到的情况。。
//今天面试写代码被面试官发现了。还是面试官厉害。
int half = (first+last)/2;
if(v[half] == value)
return half;
else if(v[half] < value)
return binarySearch(v, half, last, value);
else
return binarySearch(v, 0, half, value);
}
运行结果:
v: 0 0 2 2 2 3 6 6 8 8
2 index is 4
root@linux_ever:~/linux_ever/algorithm/ch7# ./binarySearch
v: 1 1 1 1 2 6 7 7 9 9
7 index is 6
root@linux_ever:~/linux_ever/algorithm/ch7# ./binarySearch
v: 0 0 0 2 2 5 5 7 8 9
7 index is 7
root@linux_ever:~/linux_ever/algorithm/ch7# ./binarySearch
v: 0 0 0 2 2 5 5 7 8 9
7 index is 7
root@linux_ever:~/linux_ever/algorithm/ch7# ./binarySearch
v: 0 0 1 2 5 5 6 7 8 8
5 index is 4
root@linux_ever:~/linux_ever/algorithm/ch7# ./binarySearch
v: 0 0 1 2 5 5 6 7 8 8
5 index is 4
root@linux_ever:~/linux_ever/algorithm/ch7# ./binarySearch
v: 0 0 1 1 3 6 7 9 9 9
9 index is 7
root@linux_ever:~/linux_ever/algorithm/ch7# ./binarySearch
v: 0 0 1 1 3 6 7 9 9 9
9 index is 7