使用java实现并简要分析抽象的基本静态查找算法。notes, learning from algs4.
引入
基本查找算法,我们只谈静态查找的查找算法。
线性查找 - linear search
特点:
从头开始遍历数组,一个一个和key比较,查找成功则返回索引值。
不要求数组是有序的。
时间复杂度为: O(n).
线性查找原始抽象方法实现如下:
1 2 3 4 5 6 7
publicstaticintlinearSearch(Comparable[] a, Comparable key){ for (int i = 0; i < a.length; i++) { if (a[i].compareTo(key) == 0) return i; } return -1; }
// 递归实现. publicstaticintternarySearch(Comparable[] a, Comparable key, int lo, int hi){ if (lo <= hi) { int mid1 = lo + (hi - lo) / 3; int mid2 = mid1 + (hi - lo) / 3; if (a[mid1].compareTo(key) == 0) return mid1; if (a[mid2].compareTo(key) == 0) return mid2; // 目标元素只可能出现在第一部分. if (a[mid1].compareTo(key) > 0) return ternarySearch(a, key, lo, mid1-1); // 目标元素只可能出现在第三部分. if (a[mid2].compareTo(key) < 0) return ternarySearch(a, key, mid2+1, hi); // 目标元素只可能出现在第二部分. return ternarySearch(a, key, mid1+1, mid2-1); } // 查找失败. return -1; }
指数搜索 - exponential search
特点:
找到目标元素可能出现的区间;
使用二分查找在区间上查找目标元素;
时间复杂度: logn;
[notice]:
适用于目标数组元素大小趋向于无限大的情况;
当目标出现在目标数组左边时,指数搜索速度比二分查找快。
1 2 3 4 5 6 7 8
publicstaticintexponentialSearch(Comparable[] a, Comparable key){ int n = a.length; int i = 1; while (i < n && a[i].compareTo(key) < 0) { i = i * 2; } return binarySearch(a, key, i/2, Math.min(i, n-1)); }
// java program to implement interpolatoin search. publicstaticintinterpolationSearch(Comparable[] a, Comparable key){ int lo = 0; int hi = a.length - 1; while (lo <= hi && less(key, a[hi]) && less(a[lo], key)) { int pos = lo + (hi - lo) * (key - a[lo]) / (a[hi] - a[lo]); if (a[pos].compareTo(key) == 0) return pos; elseif (a[pos].compareTo(key) > 0) hi = pos - 1; else lo = pos + 1; } return -1; }