【转】二分查找(折半查找Binary Search)

首先给五个题目:

1.给定一个有序(不降序)的数组a[],求任意一个index使得a[index]==k,不存在则返回0.

2.给定一个有序(不降序)的数组a[],求最小的index使得a[index]==k,不存在则返回0.

3.给定 一个有序(不降序)的数组a[],求最大的index使得a[index]==k,不存在则返回0.

4.给定一个有序(不降序)的数组a[],求最大的index使得a[index]小于k,不存在则返回0.

5.给定一个有序(不降序)的数组a[],求最小的index使得a[index]大于k,不存在则返回0.

        因为数组中的元素有序,因此我们采用时间复杂度较低的二分查找来做,典型的二分查找只验证是否能查找到,如果数组中存在多个k,返回不确定的任意一个index,如题目1,下面的程序中BinarySearch1,对应这种情况。

       当有多个匹配时,这些值在数组中肯定连续存储(因为数组有序)。如果程序想返回某个特定的匹配,则需控制好循环结束条件,判断语句,认真分析。

       本人认为,第4题与第2题相似,只需要将2题中的index-1即可。同理,第5题与第3题相似,只需将3题中的index+1即可。

       下面是本人写的测试程序,考虑不周全之处,还望指正!

 

  1 #include "stdafx.h"
  2 #include <iostream>
  3 
  4 using namespace std;
  5 
  6 //典型的二分查找(折半查找,Binary Search),查找成功,则返回某一个
  7 //匹配的下标(若有多个匹配,不确定返回哪一个),若查找不成功,返回0
  8 int BinarySearch1(char *a,  char k)
  9 {
 10     int low(0),high(0),mid(0); 
 11     char *p = a;
 12 
 13     while (*p != '\0')
 14     {
 15         p ++;
 16         high ++;
 17     }
 18     high --;   //high为数组最后一个元素下标
 19 
 20     while (low <= high) //注意边界条件
 21     {
 22         mid = low + (high - low)/2; //实际是mid = low + high,写成这种形式,是为了防止溢出
 23 
 24         if (a[mid] == k)
 25         {
 26             cout << "yeah,i find it, the index is: " << mid << endl;
 27             return mid;
 28         }
 29         else  if (a[mid]  > k)
 30         {
 31             high = mid - 1;
 32         }
 33         else
 34         {
 35             low = mid + 1;
 36         }
 37     }
 38     cout << "sorry , i do not find it." << endl;
 39     return 0;
 40 }
 41 
 42 //一个有序(不降序)的数组a[],求最小的index使得a[index]==i,不存在则返回0.
 43 //如char a[] = "aaahhhhhhhyyyyzzz";,则返回最小的h的下标3.
 44 char BinarySearch2(char *a, char k)
 45 {
 46     int low(0),high(0),mid(0); 
 47     char *p = a;
 48 
 49     while (*p != '\0')
 50     {
 51         p ++;
 52         high ++;
 53     }
 54     high --;
 55 
 56     while (low < high - 1) //注意边界条件
 57     {
 58         mid = low + (high - low)/2; //实际是mid = low + high,写成这种形式,是为了防止溢出
 59 
 60         if (a[mid] >= k)  //当a[mid]==k时,说明已经查找到,但不一定是最小的index,
 61         {
 62             high = mid ;
 63         }
 64         else  
 65         {
 66             low = mid;
 67         }
 68     }
 69     if (a[low] == k)  //结束时,low = high - 1,先判断a[low]是否为k
 70     {
 71         cout << "The index is :" << low << endl;
 72         return low;
 73     }
 74     else if (a[high] == k)
 75     {
 76         cout << "The index is :" << high << endl ;
 77         return high;
 78     }
 79     else
 80     {
 81         return 0;
 82     }
 83 }
 84 
 85 //一个有序(不降序)的数组a[],求最大的index使得a[index]==k,不存在则返回0.
 86 //如char a[] = "aaahhhhhhhyyyyzzz";,则返回最大的h的下标9.
 87 char BinarySearch3(char *a, char k)
 88 {
 89     int low(0),high(0),mid(0); 
 90     char *p = a;
 91 
 92     while (*p != '\0')
 93     {
 94         p ++;
 95         high ++;
 96     }
 97     high --;
 98 
 99     while (low < high - 1)
100     {
101         mid = low + (high - low)/2; //实际是mid = low + high,写成这种形式,是为了防止溢出
102 
103         if (a[mid] <= k)  //当a[mid]==k时,说明已经查找到,但不一定是最大的index,
104         {
105             low = mid ;
106         }
107         else  
108         {
109             high = mid;
110         }
111     }
112     if (a[high] == k) //结束时,low = high - 1,先判断a[high]是否为k
113     {
114         cout << "The index is :" << high << endl;
115         return high;
116     }
117     else if (a[low] == k)
118     {
119         cout << "The index is :" << low << endl;
120         return low;
121     }
122     else
123     {
124         return 0;
125     }
126 }
127 int _tmain(int argc, _TCHAR* argv[])
128 {
129     char a[] = "aaahhhhhhhyyyyzzz";
130     BinarySearch1(a, 'h');
131     BinarySearch2(a, 'h');
132     BinarySearch3(a, 'h');
133     return 0;
134 }

 

 

 

posted @ 2013-02-23 19:19  xsc906476903  阅读(182)  评论(0编辑  收藏  举报