算法3.2 有序数组中的二分查找
实现:这种符号表使用一对平行的数组,一个存储键,一个存储值,核心是rank()方法,返回表中小于给点键的键数,对于get(),只要键存在,rank()即可指明位置,put()同理
public class BinarySearchST<Key extends Comparable<Key>, Value>{private Key[] keys;private Value[] values;private int N;public BinarySearchST(int capacity){keys = (Key[])new Object[capacity];values = (Value[])new Object[capacity];}private boolean isEmpty(){ return N==0;}private int rank(Key key){int lo = 0, hi = N-1;while (lo <= hi){int mid = lo + (hi-lo)/2;int cmp = keys[mid].compareTo(key);if (cmp < 0) lo = mid+1;else if (cmp > 0) hi = mid-1;else return mid;}return lo;//return保证即便没有该键也能返回小于该键的键数}//递归实现private int rank(Key key, int lo, int hi){if(lo > hi) return lo;int mid = lo + (hi-lo)/2;int cmp = keys[mid].compareTo(key);if (cmp < 0) return rank(key, mid+1, hi);else if (cmp > 0) return rank(key, lo, mid-1);else return mid;}private int size(){ return N;}private Value get(Key key){if (isEmpty()) return null;int i = rank(key);if (i < N && keys[i].compareTo(key) == 0) return values[i];else return null;}private void put(Key key, Value value){int i = rank(key);if (i < N && keys[i].compareTo(key) == 0){values[i] = value;return;}for (int j = N-1; j >= i; j--){keys[j] = keys[j+1];values[j] = values[j+1];}keys[i] = key;values[i] = value;N++;}private void delete(Key key){if(isEmpty()) return;int i = rank(key);if (!(i < N && keys[i].compareTo(key) == 0)) return;for (int j = N-1; j > i; j--){keys[j-1] = keys[j];values[j-1] = values[j];}}}
说明
- 对于算法中递归的rank(key, 0, N-1),当表中存在该键,返回该键的位置,即排名,但即便表中不存在该键,rank()还是返回表中小于它的键的数量,当rank为迭代实现时,该性质还是满足.
算法分析
- 在N个键的有序数组中二分查找最多需要(lgN+1)次比较,无论是否成功
- 向大小N的有序数组中插入一个新元素在最坏情况下访问N²次数组
