二分查找

1、问题描述

在一个有序(升序)数组查找一个数 x

2、算法分析

暴力的做法就是拿 x 跟数组里面每个数比较一下,然后返回找到的 x 的下标。这里明显可以使用分治的思想:可以把数组分成很多部分,在每个部分里面查找 x。如果所有部分都没有找到 x,那么把这些子问题合并起来后,表示整个数组里没有 x。

这很好的反应了分治的思想,先分解成很多小问题,解决这些小问题,把解决的小问题合并起来,大问题就解决了。

BinarySearch.gif

3、代码实现

递归:

#include <stdio.h>
#include <string.h>

/**
  *  @param   a   需要二分的升序数组
  *  @param   x   需要查找的数字
  *  @param   low    低位
  *  @param   high   高位
  */
int binarysearch(int a[], int x, int low, int high)
{
    if(low > high) {
        return -1;  // 没有找到
    }
    
    int mid = (low + high) >> 1;
    
    if(x == a[mid]) {
        return mid;  // 找到 x
    }
    else if(x > a[mid]) {
        return binarysearch(a, x, mid + 1, high); // 在后半部分继续二分查找
    }
    else {
        return binarysearch(a, x, low, mid - 1); // 在前半部分继续二分查找
    }
}

int main()
{
    int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    
    int idx = binarysearch(a, 2, 0, 9);
    
    if(idx == -1) {
        printf("未查到!
");
    }
    else {
        printf("查到了!数组下标 = %d
", idx);
    }
    return 0;
}

非递归:

#include <stdio.h>

int BinarySearch(int a[], int n, int key)
{
    if (n == 0) return -1;
    
    int left = 0, mid, right = n - 1;
    
    while (left <= right) {
        mid = (left + right) >> 1;
        
        if (a[mid] < key) {
            left = mid + 1;
        }
        else if (a[mid] > key) {
            right = mid - 1;
        }
        else {
            return mid;
        }
    }
    
    return -1;
}

int main()
{
    int a[] = { 1, 3, 5, 8, 22, 45, 65, 78, 79, 102 };
    printf("%d", BinarySearch(a, 10, 65));
    return 0;
}
原文地址:https://www.cnblogs.com/dins/p/binarysearch.html