文章目录
- 
- 前言
 - 参考目录
 - 学习笔记
 - 
- 1:API
 - 1.1:遵循的规则
 - [1.2:ST 用例举例](#1.2:ST 用例举例)
 - 1.2.1:行为测试用例
 - 1.2.2:性能测试用例
 - 2:基本实现
 - 2.1:无序链表处理
 - 2.2:初级ST实现小结
 - 2.3:有序数组的二分查找
 - [2.4:二分查找 Java 代码实现](#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 包的源码贴上来:
            
            
              java
              
              
            
          
          	/**
     * 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
(完)











