2010-10-21 126 views
1

在顶部列出的binary_search函数遇到问题。不知道该去哪里。我对二进制搜索不太熟悉。二进制搜索功能的问题

#include <iostream> 
#include <cstdlib> 
#include <fstream> 

using namespace std; 

void get_input(ifstream& fin, int a[], int size, int & array_size); 

void binary_search (int a[], int & array_size) 
{ 
    cout << "Please enter the element you would like to search for \n"; 
    int element; 
    cin >> element; 

    int lastindex=array_size-1, startindex=0; 

    while (startindex <= lastindex) 
    { 
     int midindex=(array_size/2); 
     if(element > a[midindex]) 
     { 
      startindex=midindex; 
     } 
     else if (element < a[midindex]) 
     { 
      lastindex=midindex-1; 
     } 

    } 

} 

int main() 
{ 
    int array_size=-1; 
    int a[100]; 

    ifstream fin; 

    get_input (fin, a, 100, array_size); 

    binary_search (a, array_size); 

    return 0; 
} 

void get_input (ifstream& fin, int a[], int size, int & array_size) 
{ 
    fin.open("numbers.txt"); 
    if (fin.fail()) 
    { 
     cout << "File failed to open"; 
     exit(1); 
    } 


    for(int i = 0; i < size; i++) 
    { 
     a[i] = 0; 
    } 

    cout << "The numbers in the array are: \n\n"; 

    for (int i = 0; i < size; i++) 
    { 
     if (!fin.eof()) 
     { 
      fin >> a[i]; 
      array_size ++; 
     } 
    } 

    for (int i = 0; i < array_size; i++) 
    { 
      cout << a[i] << " "; 
    } 

    cout << "\n\n\n"; 
    cout << "The numbers in the array sorted are: \n\n"; 

    for(int i = 0; i < array_size; ++i) 
    { 
     int temp2 = a[i]; 

     for (int j = i+1; j < array_size; ++j) 
     { 

      if(a[j] < temp2) 
      { 
       temp2 = a[j]; 

       int temp = a[i]; 
       a[i] = a[j]; 
       a[j] = temp; 
      } 
     } 
    } 





    for (int i = 0; i < array_size; i++) 
    { 
      cout << a[i] << " "; 
    } 

    cout << "\n\n\n"; 

    fin.close(); 
} 

当完成程序时,假设从文件中获取输入将其分配给数组,然后对数组进行排序。在此之后,我需要使用二进制搜索来查找用户给出的数字,并将其在数组中的位置显示给用户。

更新:找到索引发现错误的输出....我应该只添加一个midindex?

void binary_search (int a[], int & array_size) 
{ 
    cout << "Please enter the element you would like to search for \n"; 
    int element; 
    cin >> element; 

    int lastindex=array_size-1, startindex=0; 

    while (startindex <= lastindex) 
    { 
     int midindex= startindex + (lastindex - startindex)/2; 

     if(element > a[midindex]) 
     { 
      startindex=midindex+1; 
     } 
     else if (element < a[midindex]) 
     { 
      lastindex=midindex-1; 
     } 
     else if (element == a[midindex]) 
     { 
      cout<<"Element "<<element<<" found at index "<<midindex<<endl; 
      return; 
     } 



    } 

} 
+2

凡去用它的指数?首先,你应该将I/O从搜索功能中分离出来,并将元素作为参数传递给函数。 – 2010-10-21 03:25:16

+0

为什么不使用'std :: vector','std :: swap'等? – GManNickG 2010-10-21 03:29:14

+0

@GMan不得不手动编码。或者我会。 – Zud 2010-10-21 03:31:50

回答

2

尝试改变

startindex=midindex; 

到:

startindex=midindex + 1; 

int midindex=(array_size/2); 

int midindex= startindex + (lastindex - startindex)/2 

并且最重要的是当你找到元素时你什么都不做!

if(element == a[midindex]) { 
    cout<<"Element "<<element<<" found at index "<<midindex<<endl; 
    return; 
} 
+0

是的,当我看到你的答案是'startindex = midindex + 1'时,我投票了,现在修复:) – mcabral 2010-10-21 03:21:45

+0

这工作完美,除非我没有找回正确的midindex。 – Zud 2010-10-21 03:26:02

+0

如果该元素存在于数组中,则应该得到正确的索引。你的元素是否存在于数组中? – codaddict 2010-10-21 03:30:05

2

我的第一反应就是要改变线

int midindex=(array_size/2); 

int midindex = startindex + (lastindex - startindex)/2; 

而且,你不希望如果寻求元素被发现或不报?为了检测当发现该元素的情况下,另一个分支if像下面

if(element == a[midindex]) 

可以插入。它内部可以有一个return element;return midindex,在循环外部还有一个return failure;


编辑:我做了一个不经意的尝试写一个版本的二进制搜索。我并不认为它是正确的,因为二分查找(以)为不正确而闻名。在键盘上上传Some code with test cases and output

段:

int * 
mybsearch(int const * const a, size_t const n, int const key) { 

    int * lo = const_cast< int * >(a); 
    int * hi = lo + n; 

    while(lo <= hi) { 

     int * const mid = lo + (hi - lo)/2; 
     int const midelem = *mid; 

     if(key == midelem) { 
      return mid; 
     } 
     else if(key < midelem) { 
      hi = mid - 1; 
     } 
     else { 
      lo = mid + 1; 
     } 
    } 

    return NULL; 
} 

主要和测试代码:

int main() { 

    int const arr[] = {10, 20, 30, 40, 50, 60, 70, 80, 90}; 
    size_t const num = sizeof(arr)/sizeof(int); 

    int * pos20 = mybsearch(arr, num, 20); 
    assert(pos20 && (*pos20 == 20)); 

    int * pos25 = mybsearch(arr, num, 25); 
    assert(!pos25); 

    int * pos5 = mybsearch(arr, num, 5); 
    assert(!pos5); 

    int * pos105 = mybsearch(arr, num, 105); 
    assert(!pos105); 
} 
1

二进制搜索作品很好的递归算法。传入数组和长度,检查中间值,并根据需要递归到数组的上半部分或下半部分。

+0

+1,但看起来更像是一个评论,而不是回答:) – mcabral 2010-10-21 03:18:59

0

当array_size = 1时仔细考虑int midindex=(array_size/2);的不正确之处。然后推广到array_size = 3.然后将其转换为任意奇数。这将需要在您的头部或纸上进行小型模拟。

0

你很近。你想要做这样的事情:

int binary_search ... 

这样你就可以返回元素

while (startindex < lastindex)  
{ 
    int midindex=(startindex+endindex)/2; 
    if(element = a[midindex]) { 
     return midindex; 
    } 
    else if(element > a[midindex]) 
    { 
     startindex=midindex+1; 
+0

语句int midindex =(startindex + endindex)/ 2;'易受算术溢出的影响。请参阅http://googleresearch.blogspot.com/2006/06/extra-extra-read-all-about-it-nearly.html最好写下如下内容:int midindex = startindex +(endindex - startindex)/ 2 ;' – Arun 2010-10-21 04:02:26

+0

@ArunSaha好点。谢谢 – 2010-10-21 04:04:27