二分查找算法是在有序数组中用到的较为频繁的一种算法,在未接触二分查找算法时,最通用的一种做法是,对数组进行遍历,跟每个元素进行比较,其时间为O(n).但二分查找算法则更优,因为其查找时间为O(lgn),譬如数组{1, 2, 3, 4, 5, 6, 7, 8, 9},查找元素6,用二分查找的算法执行的话,其顺序为:
1.第一步查找中间元素,即5,由于5<6,则6必然在5之后的数组元素中,那么就在{6, 7, 8, 9}中查找,
2.寻找{6, 7, 8, 9}的中位数,为7,7>6,则6应该在7左边的数组元素中,那么只剩下6,即找到了。
- 二分查找的时间复杂度是O(log(n)),最坏情况下的时间复杂度是O(n)。
- 二分查找的一个条件是待查询的数组是有序的,我们假设这里的数组是升序的。
- 二分查找的主要思路就是设定两个指针start和end分别指向数组元素的首位两端,然后比较数组中间结点arry[mid]和待查找元素。如果待查找元素小于中间元素,那么表明带查找元素在数组的前半段,那么将end=mid-1,如果待查找元素大于中间元素,那么表明该元素在数组的后半段,将start=mid+1;如果中间元素等于待查找元素,那么返回mid的值。
二分查找可以使用递归和非递归的方法来解决,下面给出代码实例。
非递归 :
class binarySearch:search { public int lookfor(int [] ar,int target) { int start=0,mid=0; int end=ar.Length-1; while (start <= end) { mid = start + (end - start) / 2; if (ar[mid] == target) return mid; else if (target < ar[mid]) end = mid-1; else start = mid + 1; } return -1; } }
递归:
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"); }