auto commit
This commit is contained in:
parent
ebb3ce62d3
commit
2e2d499a45
128
notes/算法.md
128
notes/算法.md
|
@ -31,6 +31,9 @@
|
|||
* [红黑树](#红黑树)
|
||||
* [散列表](#散列表)
|
||||
* [小结](#小结)
|
||||
* [七、其它](#七其它)
|
||||
* [汉诺塔](#汉诺塔)
|
||||
* [哈夫曼编码](#哈夫曼编码)
|
||||
* [参考资料](#参考资料)
|
||||
<!-- GFM-TOC -->
|
||||
|
||||
|
@ -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 次。
|
||||
|
||||
<div align="center"> <img src="../pics//54f1e052-0596-4b5e-833c-e80d75bf3f9b.png" width="300"/> </div><br>
|
||||
|
||||
<div align="center"> <img src="../pics//8587132a-021d-4f1f-a8ec-5a9daa7157a7.png" width="300"/> </div><br>
|
||||
|
||||
<div align="center"> <img src="../pics//2861e923-4862-4526-881c-15529279d49c.png" width="300"/> </div><br>
|
||||
|
||||
<div align="center"> <img src="../pics//1c4e8185-8153-46b6-bd5a-288b15feeae6.png" width="300"/> </div><br>
|
||||
|
||||
```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,直到遍历到根节点,根节点代表的字符的编码就是这个路径编码。
|
||||
|
||||
<div align="center"> <img src="../pics//3ff4f00a-2321-48fd-95f4-ce6001332151.png"/> </div><br>
|
||||
|
||||
```java
|
||||
public class Huffman {
|
||||
|
||||
private class Node implements Comparable<Node> {
|
||||
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<Character, String> encode(Map<Character, Integer> frequencyForChar) {
|
||||
PriorityQueue<Node> 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<Character, String> encode(Node root) {
|
||||
Map<Character, String> encodingForChar = new HashMap<>();
|
||||
encode(root, "", encodingForChar);
|
||||
return encodingForChar;
|
||||
}
|
||||
|
||||
private void encode(Node node, String encoding, Map<Character, String> 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.
|
||||
|
|
BIN
pics/1c4e8185-8153-46b6-bd5a-288b15feeae6.png
Normal file
BIN
pics/1c4e8185-8153-46b6-bd5a-288b15feeae6.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.0 KiB |
BIN
pics/2861e923-4862-4526-881c-15529279d49c.png
Normal file
BIN
pics/2861e923-4862-4526-881c-15529279d49c.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.0 KiB |
BIN
pics/3ff4f00a-2321-48fd-95f4-ce6001332151.png
Normal file
BIN
pics/3ff4f00a-2321-48fd-95f4-ce6001332151.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
BIN
pics/54f1e052-0596-4b5e-833c-e80d75bf3f9b.png
Normal file
BIN
pics/54f1e052-0596-4b5e-833c-e80d75bf3f9b.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.0 KiB |
BIN
pics/8587132a-021d-4f1f-a8ec-5a9daa7157a7.png
Normal file
BIN
pics/8587132a-021d-4f1f-a8ec-5a9daa7157a7.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.0 KiB |
Loading…
Reference in New Issue
Block a user