diff --git a/notes/算法.md b/notes/算法.md
index 18366255..207621ce 100644
--- a/notes/算法.md
+++ b/notes/算法.md
@@ -31,6 +31,9 @@
* [红黑树](#红黑树)
* [散列表](#散列表)
* [小结](#小结)
+* [七、其它](#七其它)
+ * [汉诺塔](#汉诺塔)
+ * [哈夫曼编码](#哈夫曼编码)
* [参考资料](#参考资料)
@@ -2032,6 +2035,131 @@ public class SparseVector {
}
```
+# 七、其它
+
+## 汉诺塔
+
+这是一个经典的递归问题,分为三步求解:
+
+1. 将 n-1 个圆盘从 from -> buffer
+2. 将 1 个圆盘从 from -> to
+3. 将 n-1 个圆盘从 buffer -> to
+
+如果只有一个圆盘,那么只需要进行一次移动操作,从上面的移动步骤可以知道,n 圆盘需要移动 (n-1)+1+(n-1) = 2n-1 次。
+
+
+
+
+
+
+
+
+
+```java
+public class Hanoi {
+ public static void move(int n, String from, String buffer, String to) {
+ if (n == 1) {
+ System.out.println("from " + from + " to " + to);
+ return;
+ }
+ move(n - 1, from, to, buffer);
+ move(1, from, buffer, to);
+ move(n - 1, buffer, from, to);
+ }
+
+ public static void main(String[] args) {
+ Hanoi.move(3, "H1", "H2", "H3");
+ }
+}
+```
+
+```html
+from H1 to H3
+from H1 to H2
+from H3 to H2
+from H1 to H3
+from H2 to H1
+from H2 to H3
+from H1 to H3
+```
+
+## 哈夫曼编码
+
+哈夫曼编码根据数据出现的频率对数据进行编码,从而压缩原始数据。
+
+例如对于文本文件,其中各种字符出现的次数如下:
+
+- a : 10
+- b : 20
+- c : 40
+- d : 80
+
+可以将每种字符转换成二进制编码,例如将 a 转换为 00,b 转换为 01,c 转换为 10,d 转换为 11。这是最简单的一种编码方式,没有考虑各个字符的权值(出现频率)。而哈夫曼编码能让出现频率最大的字符编码最短,从而保证最终的编码长度最短。
+
+首先生成一颗哈夫曼树,每次生成过程中选取频率最少的两个节点,生成一个新节点作为它们的父节点,并且新节点的频率为两个节点的和。选取频率最少的原因是,生成过程使得先选取的节点在树的最底层,那么需要的编码长度更长,频率更少可以使得总编码长度更少。
+
+生成编码时,从根节点出发,向左遍历则添加二进制位 0,向右则添加二进制位 1,直到遍历到根节点,根节点代表的字符的编码就是这个路径编码。
+
+
+
+```java
+public class Huffman {
+
+ private class Node implements Comparable {
+ char ch;
+ int freq;
+ boolean isLeaf;
+ Node left, right;
+
+ public Node(char ch, int freq) {
+ this.ch = ch;
+ this.freq = freq;
+ isLeaf = true;
+ }
+
+ public Node(Node left, Node right, int freq) {
+ this.left = left;
+ this.right = right;
+ this.freq = freq;
+ isLeaf = false;
+ }
+
+ @Override
+ public int compareTo(Node o) {
+ return this.freq - o.freq;
+ }
+ }
+
+ public Map encode(Map frequencyForChar) {
+ PriorityQueue priorityQueue = new PriorityQueue<>();
+ for (Character c : frequencyForChar.keySet()) {
+ priorityQueue.add(new Node(c, frequencyForChar.get(c)));
+ }
+ while (priorityQueue.size() != 1) {
+ Node node1 = priorityQueue.poll();
+ Node node2 = priorityQueue.poll();
+ priorityQueue.add(new Node(node1, node2, node1.freq + node2.freq));
+ }
+ return encode(priorityQueue.poll());
+ }
+
+ private Map encode(Node root) {
+ Map encodingForChar = new HashMap<>();
+ encode(root, "", encodingForChar);
+ return encodingForChar;
+ }
+
+ private void encode(Node node, String encoding, Map encodingForChar) {
+ if (node.isLeaf) {
+ encodingForChar.put(node.ch, encoding);
+ return;
+ }
+ encode(node.left, encoding + '0', encodingForChar);
+ encode(node.right, encoding + '1', encodingForChar);
+ }
+}
+```
+
# 参考资料
- Sedgewick, Robert, and Kevin Wayne. _Algorithms_. Addison-Wesley Professional, 2011.
diff --git a/pics/1c4e8185-8153-46b6-bd5a-288b15feeae6.png b/pics/1c4e8185-8153-46b6-bd5a-288b15feeae6.png
new file mode 100644
index 00000000..35e992f7
Binary files /dev/null and b/pics/1c4e8185-8153-46b6-bd5a-288b15feeae6.png differ
diff --git a/pics/2861e923-4862-4526-881c-15529279d49c.png b/pics/2861e923-4862-4526-881c-15529279d49c.png
new file mode 100644
index 00000000..6cc26c26
Binary files /dev/null and b/pics/2861e923-4862-4526-881c-15529279d49c.png differ
diff --git a/pics/3ff4f00a-2321-48fd-95f4-ce6001332151.png b/pics/3ff4f00a-2321-48fd-95f4-ce6001332151.png
new file mode 100644
index 00000000..266a4687
Binary files /dev/null and b/pics/3ff4f00a-2321-48fd-95f4-ce6001332151.png differ
diff --git a/pics/54f1e052-0596-4b5e-833c-e80d75bf3f9b.png b/pics/54f1e052-0596-4b5e-833c-e80d75bf3f9b.png
new file mode 100644
index 00000000..ad60a7e0
Binary files /dev/null and b/pics/54f1e052-0596-4b5e-833c-e80d75bf3f9b.png differ
diff --git a/pics/8587132a-021d-4f1f-a8ec-5a9daa7157a7.png b/pics/8587132a-021d-4f1f-a8ec-5a9daa7157a7.png
new file mode 100644
index 00000000..f77ff346
Binary files /dev/null and b/pics/8587132a-021d-4f1f-a8ec-5a9daa7157a7.png differ