▶ 书中第三章部分程序,加上自己补充的代码,包括单词频率统计,(单链表)顺序查找表,二分查找树
● 单词频率统计
1 package package01; 2 3 import edu.princeton.cs.algs4.StdIn; 4 import edu.princeton.cs.algs4.ST; 5 import edu.princeton.cs.algs4.StdOut; 6 7 public class class01 8 { 9 private class01() {} 10 11 public static void main(String[] args) 12 { 13 int distinct = 0, words = 0; 14 int minlen = Integer.parseInt(args[0]); // 第一个参数,参与统计的单词长度下限 15 ST<String, Integer> st = new ST<String, Integer>(); 16 17 for(;!StdIn.isEmpty();) 18 { 19 String key = StdIn.readString(); 20 if (key.length() < minlen) // 过短的单词不参与处理 21 continue; 22 words++; 23 if (st.contains(key)) // 已有就计数 +1,没有就新添记录 24 st.put(key, st.get(key) + 1); 25 else 26 { 27 st.put(key, 1); 28 distinct++; 29 } 30 } 31 32 String max = ""; // 迭代器遍历符号表,查找频率最高的单词 33 st.put(max, 0); 34 for (String word : st.keys()) 35 { 36 if (st.get(word) > st.get(max)) 37 max = word; 38 } 39 StdOut.println(max + " " + st.get(max)); 40 StdOut.println("distinct = " + distinct); 41 StdOut.println("words = " + words); 42 } 43 }
● (单链表)顺序查找表
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 int n; 10 private Node first; 11 12 private class Node 13 { 14 private Key key; 15 private Value val; 16 private Node next; 17 18 public Node(Key key, Value val, Node next) 19 { 20 this.key = key; 21 this.val = val; 22 this.next = next; 23 } 24 } 25 26 public class01() {} 27 28 public int size() 29 { 30 return n; 31 } 32 33 public boolean isEmpty() 34 { 35 return size() == 0; 36 } 37 38 public boolean contains(Key key) // 判断是否存在键 key 39 { 40 if (key == null) 41 throw new IllegalArgumentException("\n<contains> key == null.\n"); 42 return get(key) != null; 43 } 44 45 public Value get(Key key) // 查询元素的值 46 { 47 if (key == null) 48 throw new IllegalArgumentException("\n<get> key == null.\n"); 49 for (Node x = first; x != null; x = x.next) 50 { 51 if (key.equals(x.key)) 52 return x.val; 53 } 54 return null; 55 } 56 57 public void put(Key key, Value val) // 插入元素 58 { 59 if (key == null) 60 throw new IllegalArgumentException("\n<put> key == null.\n"); 61 if (val == null) // 空值用于删除 62 { 63 delete(key); 64 return; 65 } 66 for (Node x = first; x != null; x = x.next) 67 { 68 if (key.equals(x.key)) 69 { 70 x.val = val; 71 return; 72 } 73 } 74 first = new Node(key, val, first); 75 n++; 76 } 77 78 public void delete(Key key) // 删除元素 79 { 80 if (key == null) 81 throw new IllegalArgumentException("\n<delete> key == null.\n"); 82 first = deleteKernel(first, key); 83 } 84 85 private Node deleteKernel(Node x, Key key) // 删除元素的递归内核 86 { 87 if (x == null) 88 return null; 89 if (key.equals(x.key)) // x 头节点的键等于 key 90 { 91 n--; 92 return x.next; 93 } 94 x.next = deleteKernel(x.next, key); // 递归删除目标节点,需要用栈保存从链表开头到目标节点之间的所有节点 95 return x; 96 } 97 98 public Iterable<Key> keys() // 将单链表依次入队,构成迭代器 99 { 100 Queue<Key> queue = new Queue<Key>(); 101 for (Node x = first; x != null; x = x.next) 102 queue.enqueue(x.key); 103 return queue; 104 } 105 106 public static void main(String[] args) 107 { 108 class01<String, Integer> st = new class01<String, Integer>(); 109 for (int i = 0; !StdIn.isEmpty(); i++) 110 { 111 String key = StdIn.readString(); 112 st.put(key, i); 113 } 114 for (String s : st.keys()) 115 StdOut.println(s + " " + st.get(s)); 116 } 117 }
● 二分查找树
1 package package01; 2 3 import java.util.NoSuchElementException; 4 import edu.princeton.cs.algs4.Queue; 5 import edu.princeton.cs.algs4.StdIn; 6 import edu.princeton.cs.algs4.StdOut; 7 8 public class class01<Key extends Comparable<Key>, Value> 9 { 10 private Key[] keys; 11 private Value[] vals; 12 private int n = 0; 13 14 public class01() 15 { 16 this(2); // 省缺初始尺寸为 2 17 } 18 19 public class01(int capacity) 20 { 21 keys = (Key[]) new Comparable[capacity]; 22 vals = (Value[]) new Object[capacity]; 23 } 24 25 private void resize(int capacity) // 尺寸扩展为 capacity 26 { 27 assert capacity >= n; 28 Key[] tempk = (Key[]) new Comparable[capacity]; 29 Value[] tempv = (Value[]) new Object[capacity]; 30 for (int i = 0; i < n; i++) 31 { 32 tempk[i] = keys[i]; 33 tempv[i] = vals[i]; 34 } 35 vals = tempv; 36 keys = tempk; 37 } 38 39 public int size() 40 { 41 return n; 42 } 43 44 public boolean isEmpty() 45 { 46 return size() == 0; 47 } 48 49 public boolean contains(Key key) 50 { 51 if (key == null) 52 throw new IllegalArgumentException("\n<contains> key == null.\n"); 53 return get(key) != null; 54 } 55 56 public Value get(Key key) 57 { 58 if (key == null) 59 throw new IllegalArgumentException("\n<get> key == null.\n"); 60 if (isEmpty()) 61 return null; 62 int i = rank(key); 63 if (i < n && keys[i].compareTo(key) == 0) 64 return vals[i]; 65 return null; 66 } 67 68 public int rank(Key key) // 二分搜索 69 { 70 if (key == null) 71 throw new IllegalArgumentException("\n<rank> key == null.\n"); 72 int lo = 0, hi = n - 1; 73 for (; lo <= hi;) 74 { 75 int mid = lo + (hi - lo) / 2; 76 int cmp = key.compareTo(keys[mid]); 77 if (cmp < 0) 78 hi = mid - 1; 79 else if (cmp > 0) 80 lo = mid + 1; 81 else return mid; 82 } 83 return lo; 84 } 85 86 public void put(Key key, Value val) 87 { 88 if (key == null) 89 throw new IllegalArgumentException("\n<put> key == null.\n"); 90 if (val == null) 91 { 92 delete(key); 93 return; 94 } 95 int i = rank(key); 96 if (i < n && keys[i].compareTo(key) == 0) 97 { 98 vals[i] = val; 99 return; 100 } 101 if (n == keys.length) 102 resize(2 * keys.length); 103 for (int j = n; j > i; j--) 104 { 105 keys[j] = keys[j - 1]; 106 vals[j] = vals[j - 1]; 107 } 108 keys[i] = key; 109 vals[i] = val; 110 n++; 111 //assert check(); 112 } 113 114 public void delete(Key key) 115 { 116 if (key == null) 117 throw new IllegalArgumentException("\n<delete> key == null.\n"); 118 if (isEmpty()) 119 return; 120 int i = rank(key); 121 if (i == n || keys[i].compareTo(key) != 0) 122 return; 123 for (int j = i; j < n - 1; j++) // 删除节点时要依次挪动 124 { 125 keys[j] = keys[j + 1]; 126 vals[j] = vals[j + 1]; 127 } 128 n--; 129 keys[n] = null; // 方便垃圾回收 130 vals[n] = null; 131 if (n > 0 && n == keys.length / 4) 132 resize(keys.length / 2); 133 //assert check(); 134 } 135 136 public void deleteMin() 137 { 138 if (isEmpty()) 139 throw new NoSuchElementException("\n<deleteMin> underflow.\n"); 140 delete(min()); 141 } 142 143 public void deleteMax() 144 { 145 if (isEmpty()) 146 throw new NoSuchElementException("\n<deleteMax> underflow.\n"); 147 delete(max()); 148 } 149 150 public Key min() 151 { 152 if (isEmpty()) 153 throw new NoSuchElementException("\n<min> empty.\n"); 154 return keys[0]; 155 } 156 157 public Key max() 158 { 159 if (isEmpty()) 160 throw new NoSuchElementException("\n<max> empty.\n"); 161 return keys[n - 1]; 162 } 163 164 public Key select(int k) 165 { 166 if (k < 0 || k >= size()) 167 throw new IllegalArgumentException("\n<select> k < 0 || k >= size.\n"); 168 return keys[k]; 169 } 170 171 public Key floor(Key key) // 返回 key 的上一个元素 172 { 173 if (key == null) 174 throw new IllegalArgumentException("\n<floor> key == null.\n"); 175 int i = rank(key); 176 if (i < n && key.compareTo(keys[i]) == 0) 177 return keys[i]; 178 if (i == 0) 179 return null; 180 else return keys[i - 1]; 181 } 182 183 public Key ceiling(Key key) // 返回 key 的下一个元素 184 { 185 if (key == null) 186 throw new IllegalArgumentException("\n<ceiling> key == null.\n"); 187 int i = rank(key); 188 if (i == n) 189 return null; 190 else return keys[i]; 191 } 192 193 public int size(Key lo, Key hi) // 返回 lo 到 hi 的元素个数 194 { 195 if (lo == null) 196 throw new IllegalArgumentException("\n<size> lo == null.\n"); 197 if (hi == null) 198 throw new IllegalArgumentException("\n<size> hi == null.\n"); 199 if (lo.compareTo(hi) > 0) 200 return 0; 201 return rank(hi) - rank(lo) + (contains(hi) ? 1 : 0); 202 203 } 204 205 public Iterable<Key> keys() 206 { 207 return keys(min(), max()); 208 } 209 210 public Iterable<Key> keys(Key lo, Key hi) 211 { 212 if (lo == null) 213 throw new IllegalArgumentException("\n<keys> lo == null.\n"); 214 if (hi == null) 215 throw new IllegalArgumentException("\n<keys> lo == null.\n"); 216 Queue<Key> queue = new Queue<Key>(); 217 if (lo.compareTo(hi) > 0) 218 return queue; 219 for (int i = rank(lo); i < rank(hi); i++) 220 queue.enqueue(keys[i]); 221 if (contains(hi)) 222 queue.enqueue(keys[rank(hi)]); 223 return queue; 224 } 225 226 private boolean check() 227 { 228 for (int i = 1; i < size(); i++) 229 { 230 if (keys[i].compareTo(keys[i - 1]) < 0) 231 return false; 232 } 233 for (int i = 0; i < size(); i++) 234 { 235 if (i != rank(select(i))) 236 return false; 237 } 238 for (int i = 0; i < size(); i++) 239 { 240 if (keys[i].compareTo(select(rank(keys[i]))) != 0) 241 return false; 242 } 243 return true; 244 } 245 public static void main(String[] args) 246 { 247 class01<String, Integer> st = new class01<String, Integer>(); 248 for (int i = 0; !StdIn.isEmpty(); i++) 249 { 250 String key = StdIn.readString(); 251 st.put(key, i); 252 } 253 for (String s : st.keys()) 254 StdOut.println(s + " " + st.get(s)); 255 } 256 }