《算法》第三章部分程序 part 4
Posted cuancuancuanhao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《算法》第三章部分程序 part 4相关的知识,希望对你有一定的参考价值。
? 书中第三章部分程序,加上自己补充的代码,包括散列表、线性探查表
● 散列表
1 package package01; 2 3 import edu.princeton.cs.algs4.Queue; 4 import edu.princeton.cs.algs4.SequentialSearchST; 5 import edu.princeton.cs.algs4.StdIn; 6 import edu.princeton.cs.algs4.StdOut; 7 8 public class class01<Key, Value> 9 { 10 private static final int INIT_CAPACITY = 4; // 默认构造函数参数 11 private int n; // 待插入元素数 12 private int m; // 散列表尺寸 13 private SequentialSearchST<Key, Value>[] st; // 散列表 14 15 public class01() 16 { 17 this(INIT_CAPACITY); 18 } 19 20 public class01(int capacity) 21 { 22 m = capacity; 23 st = (SequentialSearchST<Key, Value>[]) new SequentialSearchST[m]; 24 for (int i = 0; i < m; i++) 25 st[i] = new SequentialSearchST<Key, Value>(); 26 } 27 28 public int size() 29 { 30 return n; 31 } 32 33 public boolean isEmpty() 34 { 35 return size() == 0; 36 } 37 38 private void resize(int capacity) 39 { 40 class01<Key, Value> temp = new class01<Key, Value>(capacity); 41 for (int i = 0; i < m; i++) 42 { 43 for (Key key : st[i].keys()) 44 temp.put(key, st[i].get(key)); 45 } 46 m = temp.m; 47 n = temp.n; 48 st = temp.st; 49 } 50 51 public boolean contains(Key key) 52 { 53 if (key == null) 54 throw new IllegalArgumentException(" <contains> key == null. "); 55 return get(key) != null; 56 } 57 58 private int hash(Key key) 59 { 60 return (key.hashCode() & 0x7fffffff) % m; 61 } 62 63 public Value get(Key key) 64 { 65 if (key == null) 66 throw new IllegalArgumentException(" <get> key == null. "); 67 return st[hash(key)].get(key); 68 } 69 70 public void put(Key key, Value val) 71 { 72 if (key == null) 73 throw new IllegalArgumentException(" <get> key == null. "); 74 if (val == null) 75 { 76 delete(key); 77 return; 78 } 79 if (n >= 10 * m) // 平均链表长度不小于 10,扩容 80 resize(2 * m); 81 int i = hash(key); 82 if (!st[i].contains(key)) 83 n++; 84 st[i].put(key, val); 85 } 86 87 public void delete(Key key) 88 { 89 if (key == null) 90 throw new IllegalArgumentException(" <delete> key == null. "); 91 if (!contains(key)) 92 return; 93 int i = hash(key); 94 if (st[i].contains(key)) 95 n--; 96 st[i].delete(key); 97 if (m > INIT_CAPACITY && n <= 2 * m) // 平均链表长度小于 2,缩容 98 resize(m / 2); 99 } 100 101 public Iterable<Key> keys() 102 { 103 Queue<Key> queue = new Queue<Key>(); 104 for (int i = 0; i < m; i++) 105 { 106 for (Key key : st[i].keys()) 107 queue.enqueue(key); 108 } 109 return queue; 110 } 111 112 public static void main(String[] args) 113 { 114 class01<String, Integer> st = new class01<String, Integer>(); 115 for (int i = 0; !StdIn.isEmpty(); i++) 116 { 117 String key = StdIn.readString(); 118 st.put(key, i); 119 } 120 for (String s : st.keys()) 121 StdOut.println(s + " " + st.get(s)); 122 } 123 }
● 线性探查表
1 package package01; 2 3 import edu.princeton.cs.algs4.Queue; 4 import edu.princeton.cs.algs4.StdIn; 5 import edu.princeton.cs.algs4.StdOut; 6 7 public class class01<Key, Value> 8 { 9 private static final int INIT_CAPACITY = 4; 10 private int n; 11 private int m; 12 private Key[] keys; 13 private Value[] vals; 14 15 public class01() 16 { 17 this(INIT_CAPACITY); 18 } 19 20 public class01(int capacity) 21 { 22 m = capacity; 23 n = 0; 24 keys = (Key[]) new Object[m]; 25 vals = (Value[]) new Object[m]; 26 } 27 28 public int size() 29 { 30 return n; 31 } 32 33 public boolean isEmpty() 34 { 35 return size() == 0; 36 } 37 38 private void resize(int capacity) 39 { 40 class01<Key, Value> temp = new class01<Key, Value>(capacity); 41 for (int i = 0; i < m; i++) 42 { 43 if (keys[i] != null) 44 temp.put(keys[i], vals[i]); 45 } 46 m = temp.m; 47 keys = temp.keys; 48 vals = temp.vals; 49 50 } 51 52 public boolean contains(Key key) 53 { 54 if (key == null) 55 throw new IllegalArgumentException(" <contains> key == null. "); 56 return get(key) != null; 57 } 58 59 private int hash(Key key) 60 { 61 return (key.hashCode() & 0x7fffffff) % m; 62 } 63 64 public Value get(Key key) 65 { 66 if (key == null) 67 throw new IllegalArgumentException(" <get> key == null. "); 68 for (int i = hash(key); keys[i] != null; i = (i + 1) % m) // 表荷载不会超过 1/2,所以不会绕圈 69 { 70 if (keys[i].equals(key)) 71 return vals[i]; 72 } 73 return null; 74 } 75 76 public void put(Key key, Value val) 77 { 78 if (key == null) 79 throw new IllegalArgumentException(" <get> key == null. "); 80 if (val == null) 81 { 82 delete(key); 83 return; 84 } 85 if (n >= m / 2) // 荷载超过一半了,扩容 86 resize(2 * m); 87 int i; 88 for (i = hash(key); keys[i] != null; i = (i + 1) % m) 89 { 90 if (keys[i].equals(key)) 91 { 92 vals[i] = val; 93 return; 94 } 95 } 96 keys[i] = key; 97 vals[i] = val; 98 n++; 99 } 100 101 public void delete(Key key) 102 { 103 if (key == null) 104 throw new IllegalArgumentException(" <delete> key == null. "); 105 if (!contains(key)) 106 return; 107 int i = hash(key); 108 for (; !key.equals(keys[i]); i = (i + 1) % m); // 找到目标元素 109 keys[i] = null; // 删除目标元素 110 vals[i] = null; 111 for (i = (i + 1) % m; keys[i] != null; i = (i + 1) % m) // 在下一个 null 之前,所有元素重新插入 112 { 113 Key keyToRehash = keys[i]; 114 Value valToRehash = vals[i]; 115 keys[i] = null; 116 vals[i] = null; 117 n--; 118 put(keyToRehash, valToRehash); 119 } 120 n--; 121 if (n > 0 && n <= m / 8) // 荷载小于 1/8, 缩容 122 resize(m / 2); 123 } 124 125 public Iterable<Key> keys() 126 { 127 Queue<Key> queue = new Queue<Key>(); 128 for (int i = 0; i < m; i++) 129 { 130 if (keys[i] != null) 131 queue.enqueue(keys[i]); 132 } 133 return queue; 134 } 135 private boolean check() 136 { 137 if (m < 2 * n) // 检查容量 138 { 139 System.err.println(" <check> m < 2 * n. "); 140 return false; 141 } 142 for (int i = 0; i < m; i++) // 检查 hash 143 { 144 if (keys[i] == null) 145 continue; 146 if (get(keys[i]) != vals[i]) 147 { 148 System.err.println(" <check> hash error at i = ", i, ", key[i] = ", get(keys[i]), ", val[i] = ", vals[i], ". "); 149 return false; 150 } 151 } 152 return true; 153 } 154 155 public static void main(String[] args) 156 { 157 class01<String, Integer> st = new class01<String, Integer>(); 158 for (int i = 0; !StdIn.isEmpty(); i++) 159 { 160 String key = StdIn.readString(); 161 st.put(key, i); 162 } 163 for (String s : st.keys()) 164 StdOut.println(s + " " + st.get(s)); 165 } 166 }
以上是关于《算法》第三章部分程序 part 4的主要内容,如果未能解决你的问题,请参考以下文章