文章目录
- 前言
- 参考目录
- 学习笔记
- 1:API
- 1.1:遵循的规则
- 1.2:ST 用例举例
- 1.2.1:行为测试用例
- 1.2.2:性能测试用例
- 2:基本实现
- 2.1:无序链表处理
- 2.2:初级ST实现小结
- 2.3:有序数组的二分查找
- 2.4:二分查找 Java 代码实现
- 2.5:初级ST实现小结
- 3:排序操作
前言
本文的主要内容是 符号表(symbol table,以下简称 ST)。内容比较简单,只涉及到比较基础的实现,没有太过复杂的概念,因而篇幅比较短。
在 Sedgewick 教授的视频课程中对一些数学模型分析内容没有进行详细的证明,但在书中有比较详细的介绍,可以参考书中的相关章节进行学习总结。
参考目录
- B站 普林斯顿大学《Algorithms》视频课
(请自行搜索。主要以该视频课顺序来进行笔记整理,课程讲述的教授本人是该书原版作者之一 Robert Sedgewick。) - 微信读书《算法(第4版)》
(本文主要内容来自《3.1 符号表》) - 官方网站
(有书本配套的内容以及代码)
学习笔记
注1:下面引用内容如无注明出处,均是书中摘录。
注2:所有 demo 演示均为视频 PPT demo 截图。
1:API
键值对抽象。
- 插入带有指定键的值。
- 给定一个键,可以查询到对应的值。
表3.1.1 典型的符号表应用
关联数组抽象。
表3.1.2 一种简单的泛型符号表API
1.1:遵循的规则
(这里列出书中对应的章节)
- 3.1.1.1 泛型
Generics.
- 3.1.1.2 重复的键
Duplicate keys.
- 3.1.1.3 空(null)键
- 3.1.1.4 空(null)值
Null values.
- 3.1.1.5 删除操作
Deletion.
- 3.1.1.6 便捷方法
- 3.1.1.7 迭代
Iterators.
- 3.1.1.8 键的等价性
Key equality.
其中教授着重提到的是重复键规则:
以及键的等价性:
(截图自官网)
键的等价性这里给出的源码是 Person
(传送门)。
这个类的定义遵循了上面所述的一些原则。
1.2:ST 用例举例
我们这里考察两个用例:一个用来跟踪算法在小规模输入下的行为测试用例,和一个用来寻找更高效的实现的性能测试用例。
1.2.1:行为测试用例
edu.princeton.cs.algs4.ST
1.2.2:性能测试用例
edu.princeton.cs.algs4.FrequencyCounter
main 方法有点长,我直接把 jar 包的源码贴上来:
/**
* Reads in a command-line integer and sequence of words from
* standard input and prints out a word (whose length exceeds
* the threshold) that occurs most frequently to standard output.
* It also prints out the number of words whose length exceeds
* the threshold and the number of distinct such words.
*
* 中译:从标准输入读入命令行整数和单词序列,并将最常出现的单词 (其长度超过阈值) 打印到标准输出。
* 它还打印出长度超过阈值的单词的数量以及不同的此类单词的数量。
*
* @param args the command-line arguments
*/
public static void main(String[] args) {
int distinct = 0, words = 0;
int minlen = Integer.parseInt(args[0]);
ST<String, Integer> st = new ST<String, Integer>();
// compute frequency counts
while (!StdIn.isEmpty()) {
String key = StdIn.readString();
if (key.length() < minlen) continue;
words++;
if (st.contains(key)) {
st.put(key, st.get(key) + 1);
}
else {
st.put(key, 1);
distinct++;
}
}
// find a key with the highest frequency count
String max = "";
st.put(max, 0);
for (String word : st.keys()) {
if (st.get(word) > st.get(max))
max = word;
}
StdOut.println(max + " " + st.get(max));
StdOut.println("distinct = " + distinct);
StdOut.println("words = " + words);
}
2:基本实现
2.1:无序链表处理
对应章节:3.1.4 无序链表中的顺序查找
数据结构。维护键值对的(无序)链表。
搜索。扫描所有的键,直到找到一个匹配。
插入。扫描所有键,直到找到匹配项;如果没有匹配,则添加到前面。
edu.princeton.cs.algs4.SequentialSearchST
2.2:初级ST实现小结
2.3:有序数组的二分查找
对应章节:3.1.5 有序数组中的二分查找
2.4:二分查找 Java 代码实现
edu.princeton.cs.algs4.BinarySearchST
edu.princeton.cs.algs4.BinarySearchST#get
edu.princeton.cs.algs4.BinarySearchST#rank
需要注意的问题:在插入新值的时候,需要和所有较大的key进行交换。
2.5:初级ST实现小结
书里面也有汉化表格:
表3.1.10 简单的符号表实现的成本总结
3:排序操作
表3.1.4 一种有序的泛型符号表的API
(完)