算法3.2 有序数组中的二分查找

实现:这种符号表使用一对平行的数组,一个存储键,一个存储值,核心是rank()方法,返回表中小于给点键的键数,对于get(),只要键存在,rank()即可指明位置,put()同理

  1. public class BinarySearchST<Key extends Comparable<Key>, Value>{
  2. private Key[] keys;
  3. private Value[] values;
  4. private int N;
  5. public BinarySearchST(int capacity){
  6. keys = (Key[])new Object[capacity];
  7. values = (Value[])new Object[capacity];
  8. }
  9. private boolean isEmpty(){ return N==0;}
  10. private int rank(Key key){
  11. int lo = 0, hi = N-1;
  12. while (lo <= hi){
  13. int mid = lo + (hi-lo)/2;
  14. int cmp = keys[mid].compareTo(key);
  15. if (cmp < 0) lo = mid+1;
  16. else if (cmp > 0) hi = mid-1;
  17. else return mid;
  18. }
  19. return lo;//return保证即便没有该键也能返回小于该键的键数
  20. }
  21. //递归实现
  22. private int rank(Key key, int lo, int hi){
  23. if(lo > hi) return lo;
  24. int mid = lo + (hi-lo)/2;
  25. int cmp = keys[mid].compareTo(key);
  26. if (cmp < 0) return rank(key, mid+1, hi);
  27. else if (cmp > 0) return rank(key, lo, mid-1);
  28. else return mid;
  29. }
  30. private int size(){ return N;}
  31. private Value get(Key key){
  32. if (isEmpty()) return null;
  33. int i = rank(key);
  34. if (i < N && keys[i].compareTo(key) == 0) return values[i];
  35. else return null;
  36. }
  37. private void put(Key key, Value value){
  38. int i = rank(key);
  39. if (i < N && keys[i].compareTo(key) == 0){
  40. values[i] = value;
  41. return;
  42. }
  43. for (int j = N-1; j >= i; j--){
  44. keys[j] = keys[j+1];
  45. values[j] = values[j+1];
  46. }
  47. keys[i] = key;
  48. values[i] = value;
  49. N++;
  50. }
  51. private void delete(Key key){
  52. if(isEmpty()) return;
  53. int i = rank(key);
  54. if (!(i < N && keys[i].compareTo(key) == 0)) return;
  55. for (int j = N-1; j > i; j--){
  56. keys[j-1] = keys[j];
  57. values[j-1] = values[j];
  58. }
  59. }
  60. }

说明

  • 对于算法中递归的rank(key, 0, N-1),当表中存在该键,返回该键的位置,即排名,但即便表中不存在该键,rank()还是返回表中小于它的键的数量,当rank为迭代实现时,该性质还是满足.

算法分析

  • 在N个键的有序数组中二分查找最多需要(lgN+1)次比较,无论是否成功
  • 向大小N的有序数组中插入一个新元素在最坏情况下访问N²次数组