|
3 | 3 | import io.github.dunwu.algorithm.search.Search; |
4 | 4 |
|
5 | 5 | /** |
| 6 | + * 二分查找又称折半查找,它是一种效率较高的查找方法。 |
| 7 | + * 二分查找需要两个前提:(1) 必须是顺序存储结构。(2) 必须是有序的表。 |
| 8 | + * 算法: |
| 9 | + * 从数据结构线形表的一端开始,顺序扫描,依次将扫描到的结点关键字与给定值k相比较,若相等则表示查找成功; |
| 10 | + * 若扫描结束仍没有找到等于关键字的结点,表示查找失败。 |
| 11 | + * 算法分析: |
| 12 | + * 最坏情况 O(log n) |
| 13 | + * 最好情况 O(1) |
| 14 | + * 平均情况 O(log n) |
| 15 | + * 最坏情况下的空间复杂性 O(1) |
| 16 | + * |
6 | 17 | * @author Zhang Peng |
7 | | - * @date 2018/4/18 |
8 | 18 | */ |
9 | 19 | public class BinarySearch implements Search { |
10 | 20 |
|
| 21 | + /** |
| 22 | + * 查找方法 |
| 23 | + * |
| 24 | + * @param array 被查找的线性表 |
| 25 | + * @param key 被查找的 key |
| 26 | + * @return 成功返回 key 的位置;失败返回 -1 |
| 27 | + */ |
11 | 28 | @Override |
12 | | - public int search(int[] list, int key) { |
13 | | - int low = 0, mid = 0, high = list.length - 1; |
14 | | - while (low <= high) { |
15 | | - mid = (low + high) / 2; |
16 | | - if (list[mid] == key) { |
17 | | - return mid; // 查找成功,直接返回位置 |
18 | | - } else if (list[mid] < key) { |
19 | | - low = mid + 1; // 关键字大于中间位置的值,则在大值区间[mid+1, high]继续查找 |
20 | | - } else { |
21 | | - high = mid - 1; // 关键字小于中间位置的值,则在小值区间[low, mid-1]继续查找 |
22 | | - } |
| 29 | + public <T extends Comparable<T>> int find(T array[], T key) { |
| 30 | + return search(array, key, 0, array.length); |
| 31 | + } |
| 32 | + |
| 33 | + private <T extends Comparable<T>> int search(T array[], T key, int left, int right) { |
| 34 | + // this means that the key not found |
| 35 | + if (right < left) { |
| 36 | + return -1; |
| 37 | + } |
| 38 | + |
| 39 | + int mid = (left + right) >>> 1; |
| 40 | + int comp = key.compareTo(array[mid]); |
| 41 | + |
| 42 | + if (comp < 0) { |
| 43 | + return search(array, key, left, mid - 1); |
| 44 | + } |
| 45 | + |
| 46 | + if (comp > 0) { |
| 47 | + return search(array, key, mid + 1, right); |
23 | 48 | } |
24 | | - return -1; |
| 49 | + |
| 50 | + return mid; |
25 | 51 | } |
26 | 52 | } |
0 commit comments