摘要
二分法查找:又称折半查找。适用于有序数据集合的目标值查找。
二分法思想:假设有一个按升序排好序的数列data,查找目标值target,过程如下:
1.将数列进行折半,判断data[mid]是否等于target, 相等则返回index, 否则,判断中间值和target大小;
2.若 target > data[mid],将data右一半执行第一步,否则,将data左一半执行第一步;
3.返回index
code
废话不多说,上代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public class BinarySearch {
public int getIndex(int[] data, int target) {
int left = 0; int right = data.length - 1;
while (left <= right) { int mid = left + (right - left) / 2; if(data[mid] == target) { return mid; } else if(data[mid] < target) { left = mid + 1; } else { right = mid - 1; } } return -1; } }
|
变异
假如数列中出现了重复项,那我们查到的index便不确定,那如何在重复项得到最小的一个位置呢?
二分查找 + 顺序查找
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| public int getRepeatIndex(int[] data, int target) { int left = 0; int right = data.length - 1; while (left <= right) { int mid = left + (right - left) / 2; if(data[mid] == target) { while (mid >= 0) { if(data[mid] != target) { break; } mid --; } return mid + 1; } else if(data[mid] < target) { left = mid + 1; } else { right = mid - 1; } } if(data[left] == target) { return left; } else { return -1; } }
|
二分法到底
可能大多数考虑到上述的情况就结束了,仔细想想,还可不可以更快一点儿呢,回答是肯定的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public int getRepeatIndex(int[] data, int target) { int left = 0; int right = data.length - 1; if(data.length == 0) { return -1; } while (left < right) { int mid = left + (right - left) / 2; if(data[mid] >= target) { right = mid; } else { left = mid + 1; } } if(data[left] == target) { return left; } else { return -1; } }
|