c/c++ 实战之二分查找

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sumsear/article/details/78012659
二分查找的必要条件

数组或者集合有序,或者存在一种关系 –> 满足条件与不满足条件的数据能够按照某种标准分成两部分。最简单的就是基本数据类型的数组了。

比如说:我们声明了一个数组 ,如下:

int array [] = {0,1,2,3,4,5,6,7,8,9,10};

假设我们要查询这个数组中是否存在一个值9,如果是采用for循环遍历的话,那么我们需要遍历10次这个数组,显然当数据较多且我们要查询的值有可能在数组的尾端时,那么这种查询方法的效率并不高。所以机智的人类想到了这种二分查找法,其原理也相当的简单。
比如上面这个例子,我们在查找数组中是否含有9这个值时,先取数组的中间位置,也就是index == 5的值进行判断,如果 9 == array[5] 那么恭喜!我们刚好查到我们想要的结果,如果9 > array[5]则说明在有序数组中,我们要查找的值应该位于array[5] 的右侧,否则位于array[5]的左侧,很明显 9 > 5 所以,我们要查询的值在5的右侧,然后我们再取array[6] ~ array[10]的中间值查询,即array[8],我们发现
9 > 8,那么值还在array[8]的右侧。依此类推,我们只需再查一次便可获取到结果。对比原始的for循环,我们只花了3次便获取到了结果。其效率非常之高。
下面上c++代码:

C++ 二分查找实现
// CppArray.cpp : 定义控制台应用程序的入口点。

#include "stdafx.h"     
#define GET_ARRAY_LEN(array,len) {len=sizeof(array)/sizeof(array[0]);}

//统计查询次数    
int count = 0;

//折半查找
int binarySearch(int* array, int start, int end, int search) {

    int median = (start + end) / 2;

    if (search < *(array + median)) {
        //因为search小于数组中间位置的值,说明在有序数组中要查询的结果应该位于中间位置的值的左侧
        if (median - 1 < 0)
        {
            return -1;
        }
        return binarySearch(array, start, median, search);
    }
    else if (search > *(array + median))
    {
        //因为search大于数组中间位置的值,说明在有序数组中要查询的结果应该位于中间位置的值的右侧
        if (median + 1 >= end)
        {
            return -1;
        }
        return binarySearch(array, median, end, search);
    }
    else
    {
        return search;
    }
}

int main()
{
    int num[] = { 0,1,2,3,4,5,6,7,8,9,10,11,12 };
    int len;
    GET_ARRAY_LEN(num, len);

    for (int i = 13; i >-3; i--)
    {
        count = 0;
        int result = binarySearch(num, 0, len, i);
        printf("查询结果 = %d,共花了%d次\n",result, count);
    }
    return 0;
}

正如代码中所示,我们从13开始一直查询到-2,结果如图所示:
这里写图片描述

我们要查询的值最多的也才花费4次。当然对于数据不大的话使用这种查询可能没什么必要,但是当数据量大的时候,比如查询一个长度为250的数组,那效率就不一般了,在Android中用过SparseArray或者有去了解过SparseArray具体实现的各位大佬们一定深有体会!

猜你喜欢

转载自blog.csdn.net/sumsear/article/details/78012659