【Algorithm】二分查找

    今天在学习《编程之美》的时候,看到一个二分查找的题目,发现原来我真的不懂二分查找。

  二分查找时候注意的事项:

  1.   

    在求二分查找的中间点时没有使用

    midIndex = (minIndex + maxIndex) / 2

    是因为,以免 minIndex + maxIndex之后会导致溢出而出现错误。

  2. 注意循环的循环终止条件及边界元素的判定。

    下面把牛人做的该题部分的扩展(C++)拿来展示一下,以供学习:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <iostream>
using namespace std;

/*
//1: 给定一个有序(不降序)数组arr,求最大的i使得arr[i]等于v,不存在则返回-1
int bisearch(char arr[][10], int begin, int end, char *v)
{
    int minIndex = begin;
    int maxIndex = end;
    int midIndex;

    while(minIndex < maxIndex - 1) {
        midIndex = minIndex + (maxIndex - minIndex) / 2;

        if(strcmp(arr[midIndex], v) <= 0)
            minIndex = midIndex;
        else
            maxIndex = midIndex;
    }

    //从最大索引开始判断
    if(!strcmp(arr[maxIndex], v))
        return maxIndex;
    else if(!strcmp(arr[minIndex], v))
        return minIndex;
    else
        return -1;
}
*/

/*
//2: 一个有序(不降序)数组arr,求任意一个i使得arr[i]等于v,不存在则返回-1
int bisearch(char (*arr)[10], int begin, int end, char *v)
{
    int minIndex = begin;
    int maxIndex = end;
    int midIndex;
    while(minIndex < maxIndex) {
       
       midIndex = minIndex + (maxIndex - minIndex) / 2;
       
       if(strcmp(*(arr + midIndex), v) < 0)
           minIndex = midIndex + 1;
       else if(strcmp(*(arr + midIndex), v) > 0)
           maxIndex = midIndex - 1;
       else
           return midIndex;
    }

    cout << "minIndex = " << minIndex << " maxIndex = " << maxIndex << endl;
    
    if(!strcmp(*(arr + minIndex), v))
        return minIndex;

    return -1;
}
*/

/*
//3:给定一个有序(不降序)数组arr,求最小的i使得arr[i]等于v,不存在则返回-1
int bisearch(char (*arr)[10], int begin, int end, char *v)
{
    int minIndex = begin;
    int maxIndex = end;
    int midIndex;

    while(minIndex < maxIndex - 1) {
        midIndex = minIndex + (maxIndex - minIndex) / 2;
        if(strcmp(*(arr + midIndex), v) < 0)
            minIndex = midIndex;
        else
            maxIndex = midIndex;
    }

    cout << "minIndex = " << minIndex << " maxIndex = " << maxIndex << endl;

    //从最小数开始判断
    if(!strcmp(*(arr + minIndex), v))
        return minIndex;
    else if(!strcmp(*(arr + maxIndex), v))
        return maxIndex;
    else
        return -1;
}
*/

/*
//4:给定一个有序(不降序)数组arr,求最大的i使得arr[i]小于v,不存在则返回-1
int bisearch(char (*arr)[10], int begin, int end, char *v)
{
    int minIndex = begin;
    int maxIndex = end;
    int midIndex;

    while(minIndex < maxIndex - 1) {
        midIndex = minIndex + (maxIndex - minIndex) / 2;
        if(strcmp(*(arr + midIndex), v) < 0)
            minIndex = midIndex;
        else
            maxIndex = midIndex;
    }

    //从最大数开始判断
    if(strcmp(*(arr + maxIndex), v) < 0)
        return maxIndex;
    else if(strcmp(*(arr + minIndex), v) < 0)
        return minIndex;
    else
        return -1;
}
*/


//5; 给定一个有序(不降序)数组arr,求最小的i使得arr[i]大于v,不存在则返回-1
int bisearch(char (*arr)[10], int begin, int end, char *v)
{
    int minIndex = begin;
    int maxIndex = end;
    int midIndex;

    while(minIndex < maxIndex - 1) {
        midIndex = minIndex + (maxIndex - minIndex) / 2;
        
        if(strcmp(*(arr + midIndex), v) <= 0)
            minIndex = midIndex;
        else
            maxIndex = midIndex;
    }

    //从小数开始判断
    if(strcmp(*(arr + minIndex), v) > 0)
        return minIndex;
    else if(strcmp(*(arr + maxIndex), v) > 0)
        return maxIndex;
    else
        return -1;
}



int main()
{
    char a[][10] = {"abc", "bcd", "bddaaa", "ddcd", "ddd", "ddd", "ddd", "ddd", "xxx", "xxxx"};
    char v[] = "dddd";
    int last = sizeof(a) / (sizeof(char) * 10);
    int index = bisearch(a, 0, last-1, v);
    printf("index of v is %d\n", index);

    return 0;
}

参考资料

  [1]http://blog.csdn.net/caryaliu/article/details/8134041

posted @ 2014-08-26 20:36  NW_KNIFE  阅读(548)  评论(0编辑  收藏  举报