參考文獻:
http://blog.minidx.com/2008/02/03/468.html
正文
在面試的時候二分查找是用的比較多一種查找算法,如何在面試官面前快速准確得的寫出代碼決定你是否能夠被錄取。以前一直以為二分查找很簡單,所以就沒怎么重視,但是真要在面試官面前對着黑板手寫出來,還是漏洞百出。今天自己在電腦面前敲出了二分查找的代碼,也花了將近半個小時。對於這種基礎排序查找算法,還是得好好重視。
- 二分查找的時間復雜度是O(log(n)),最壞情況下的時間復雜度是O(n)。
- 二分查找的一個條件是待查詢的數組是有序的,我們假設這里的數組是升序的。
- 二分查找的主要思路就是設定兩個指針start和end分別指向數組元素的收尾兩端,然后比較數組中間結點arry[mid]和待查找元素。如果待查找元素小於中間元素,那么表明帶查找元素在數組的前半段,那么將end=mid-1,如果待查找元素大於中間元素,那么表明該元素在數組的后半段,將start=mid+1;如果中間元素等於待查找元素,那么返回mid的值。
二分查找可以使用遞歸和非遞歸的方法來解決,下面給出代碼實例。

#include<iostream> #include<stdlib.h> using namespace std; //不適用遞歸,如果存在返回數組位置,不存在則返回-1 int BinarySearch(int arry[],int len,int value) { //如果傳入的數組為空或者數組長度<=0那么就返回-1。防御性編程 if(arry==NULL||len<=0) return -1; int start=0; int end=len-1; while(start<=end)//判斷清是否有= { int mid=start+(end-start)/2; if(arry[mid]==value) return mid; else if(value<arry[mid]) end=mid-1; else start=mid+1; } return -1; } //改進思路:1.不要傳參,而是傳引用調用,減少垃圾 // 2.使用模板 int BinarySearchRecursion(int arry[],int value,int start,int end) { if(start>end) return -1; int mid=start+(end-start)/2; if(arry[mid]==value) return mid; else if(value<arry[mid]) return BinarySearchRecursion(arry,value,start,mid-1); else return BinarySearchRecursion(arry,value,mid+1,end); } int BinarySearchRecursion(int arry[],int len,int value) { //如果傳入的數組為空或者數組長度<=0那么就返回-1。防御性編程 if(arry==NULL||len<=0) return -1; return BinarySearchRecursion(arry,value,0,len-1); } void main() { int arry[]={1,2,3,4,5,6,7,8}; int len=sizeof(arry)/sizeof(int); int index=BinarySearch(arry,len,4); cout<<"index:"<<index<<endl; int index2=BinarySearchRecursion(arry,len,9); cout<<"index2:"<<index2<<endl; system("pause"); }
在上述遞歸的二分查找方法中:
int BinarySearchRecursion(int arry[],int value,int start,int end)
我們可以發現這個方法中的后三個參數value,start,end采用的是傳值調用,只有第一個參數arry是傳址調用。我們知道在效率方面,傳值調用要比傳址調用來的低,因為傳值調用要進行一次變量的拷貝,而傳址調用則是直接對這個變量進行操作。因此這里我們可以將后面的三個參數改為傳址調用
改進后的代碼實例如下:

int BinarySearchRecursion(int arry[],int &value,int &start,int &end) { if(start>end) return -1; int mid=start+(end-start)/2; if(arry[mid]==value) return mid; else if(value<arry[mid]) { end=mid-1; return BinarySearchRecursion(arry,value,start,end); } else { start=mid+1; return BinarySearchRecursion(arry,value,start,end); } } int BinarySearchRecursion(int arry[],int &len,int &value) { //如果傳入的數組為空或者數組長度<=0那么就返回-1。防御性編程 if(arry==NULL||len<=0) return -1; int start=0; int end=len-1; return BinarySearchRecursion(arry,value,start,end); } void main() { int arry[]={1,2,3,4,5,6,7,8}; int len=sizeof(arry)/sizeof(int); int especteNum1=4; int especteNum2=9; int index=BinarySearch(arry,len,especteNum1); cout<<"index:"<<index<<endl; int index2=BinarySearchRecursion(arry,len,especteNum2); cout<<"index2:"<<index2<<endl; system("pause"); }