二分查找(折半查找)
转自:http://blog.163.com/yuang_yu_ping/blog/static/469328762009922102736155/
1、二分查找(Binary Search)
二分查找又称折半查找,它是一种效率较高的查找方法。
二分查找要求:线性表是有序表,即表中结点按关键字有序,并且要用向量作为表的存储结构。不妨设有序表是递增有序的。
2、二分查找的基本思想
二分查找的基本思想是:(设R[low..high]是当前的查找区间)
(1)首先确定该区间的中点位置:
(2)然后将待查的K值与R[mid].key比较:若相等,则查找成功并返回此位置,否则须确定新的查找区间,继续二分查找,具体方法如下:
①若R[mid].key>K,则由表的有序性可知R[mid..n].keys均大于K,因此若表中存在关键字等于K的结点,则该结点必定是在位置mid左边的子表R[1..mid-1]中,故新的查找区间是左子表R[1..mid-1]。
②类似地,若R[mid].key<K,则要查找的K必在mid的右子表R[mid+1..n]中,即新的查找区间是右子表R[mid+1..n]。下一次查找是针对新的查找区间进行的。
因此,从初始的查找区间R[1..n]开始,每经过一次与当前查找区间的中点位置上的结点关键字的比较,就可确定查找是否成功,不成功则当前的查找区间就缩小一半。这一过程重复直至找到关键字为K的结点,或者直至当前的查找区间为空(即查找失败)时为止。
Java实现
1 /** 2 * 二分查找算法,时间复杂度: log2(n) 3 * @author Bruke 4 * 5 */ 6 public class BinarySearch { 7 /* 8 * 非递归形式 9 */ 10 public static int binary(int[] array, int value) 11 { 12 int low = 0; 13 int high = array.length - 1; 14 while(low <= high){ 15 int middle = (low + high) / 2; 16 if(value == array[middle]){ 17 return middle; 18 } 19 if(value > array[middle]){ 20 low = middle + 1; 21 } 22 if(value < array[middle]){ 23 high = middle - 1; 24 } 25 } 26 return -1; 27 } 28 /* 29 * 递归形式 30 */ 31 public int IterBiSearch(int data[], int x, int beg, int last) 32 { 33 int mid = -1; 34 mid = (beg + last) / 2; 35 if (x == data[mid]) 36 { 37 return mid; 38 } 39 else if (x < data[mid]) 40 { 41 return IterBiSearch(data, x, beg, mid - 1); 42 } 43 else if (x > data[mid]) 44 { 45 return IterBiSearch(data, x, mid + 1, last); 46 } 47 return -1; 48 } 49 public static void main(String[] args) 50 { 51 int[] a = {1, 2, 3, 4, 5, 6, 7, 8, 9}; 52 int value = binary(a, 4); 53 System.out.println(value); 54 } 55 }