数据结构与算法——二分查找算法

在一个无序的数据序列中查找某一个数值,我们只能遍历该序列的每一个数值,并与要查找的数值比较。时间复杂度为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

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值