一、定义
又称“折半查找”,需要原始数据有序存储。
二、思想
假设原始数据按升序存储,查找的值为x,首先取出中间的值midValue(取法:(left+right)/2),如果x>midValue,证明值在右边,从右边数据中继续查找,如果x<midValue,值在左边,从左边的数据中查找,依次循环以上步骤。
三、代码
public static int search(int[] arr,int left,int right,int value) { //场景1。3个数,中间值为1,value大于中间值时,左边:mid+1=2,right=2,继续查找,此时中间值是2,mid+1=3,左边大于右边。 //场景2。3个数,中间值为1,value小于中间值时,左边:left=0,right=mid-1=0,继续查找,此时中间值是0,mid-1=-1,左边大于右边。 if (left > right //如果左边的值大于value,有序序列中无此值。 || arr[left] > value //如果右边的值小于value,有序序列中无此值。 || arr[right] < value) { return -1; } int mid = (left + right)/2; int midValue = arr[mid]; while(true) { if( value > midValue) { return search(arr, mid+1, right, value); }else if(value < midValue) { return search(arr, left, mid-1, value); }else { return mid; } } } |
public static List<Integer> search2(int[] arr,int left,int right,int value) { List<Integer> list = new ArrayList<>(); if(left > right || arr[left] > value || arr[right] < value) { return list; } int mid = (left + right)/2; int midValue = arr[mid]; while(true) { if( value > midValue) { return search2(arr, mid+1, right, value); }else if(value < midValue) { return search2(arr, left, mid-1, value); }else { int temp = mid -1; while(true) { if (temp <0 || arr[temp] != value) { break; } list.add(temp); temp --; } list.add(mid); temp = mid +1; while(true) { temp ++; if (temp >arr.length || arr[temp] != value) { break; } list.add(temp); } return list; } } } |