3.1.2 有序的符号表

典型的应用程序中,键都是Comparable的对象,因此可以使用a.compare(b)来比较a和b两个键。许多符号表的实现都利用Comparable接口带来的键的有序性来更好地实现put()和get()方法。更重要的事在这些实现中,我们可以认为符号表都会保持键的有序并大大扩展它的API,根据键的相对位置定义更多实用的操作。例如,假设键是时间,你肯呢个会对最早或是最晚或是给定时间段内的所有键等感兴趣。在大多数情况下实现put()和get()方法背后的数据结构都不难实现这些操作。

只要你见到类的声明中含有泛型变量Key extends Comparable<Key>,那就说明这段程序是在实现这份API,其中的代码以来于Comparable的键并且实现了更加丰富的操作。上面所有的操作一起为用例定义了一个有序符号表。

3.1.2.1 最大键和最小键

对于一组有序的键,最自然的反应就是查询其中的最佳键和最小键。我们在讨论优先队列时已经遇到过这些操作。在有序符号表中,我们也有方法删除最大键和最小键(以及它们所关联的值)。有了这些,符号表就具有了类似于优先队列中的IndexMinPQ()的能力。主要的区别在于优先队列中可以存在重复的键但符号表中不行,而且有序符号表支持的操作更多。

3.1.2.2 向下取整和向上取整

对于给定的键,向下取整(floor)操作(找出小于等于该键的最大值)和向上取证(ceiling)操作(找出小于等于该键的最小值)有时是很有用的。这两个术语来自实数的取整函数(对一个实数向下取整即为小于等于x的最大整数,向上取证则为大于等于x的最小整数)。

3.1.2.3 排名和选择

检验一个新的键是否插入合适位置的基本操作是排名(rank,找出小于制定键的键的数量)和选择(select,找出排名为k的键)。要测试一下你是否完全理解了它们的作用,请确认对于0到size() – 1的所有i都有i == rank(select(i)),且所有的键都满足key == select(rank(key))。有序符号表的操作如下表所示。

3.1.2.4 范围查找

给定范围内(在两个给定的键之间)有多少键?是哪些?在很多应用中能够回答这些问题并接受两个参数的size()和keys()方法都很有用,特别是在大型数据库中。能够处理这类查询是有序符号表在实践中被广泛应用的重要原因之一,

3.1.2.5 例外情况

当一个方法需要返回一个键但表中却没有任何的键可以返回时,我们约定抛出一个异常(另一种合理的方法是在这种情况下返回空)。例如,在符号表为空时,min()、max()、deleteMin()、deleteMax()、floor()和ceiling()都会抛出异常,当k<0或k>=size()和select(k)也会抛出异常。

3.1.2.6 便携方法

在基础API中文名已经见过了contain()和isEmpty()方法,为了用例的清晰我们又在API中添加了一些冗余的方法。于是我们约定所有符号表API的实现都含有如下所示方法。

方法 默认的实现
void deleteMix() delete(min());
void deleteMax() delete(max());
int size(Key lo, Key)

if (hi.compareTo(lo) < 0)

  return 0;

else if (contains(hi))

  return rank(hi) - rank(lo) + 1;

else

  return rank(hi) = rank(lo);

Iterable<Key> keys() return keys(min(), max());

3.1.2.7 (再谈)键的等价性

Java的一条最佳实践就是维护所有Comparable()类型中compareTo()方法和equals()方法的一致性。也就是说,任何一种Comparable类型的两个值a和b都要保(a.compareTo(b) == 0)和e.equals(b)的返回值相同。为了避免任何潜在的二义性,我们不会在有序符号表的实现中使用equals()方法。作为代替,我们只会使用compareTo()方法来表叫两个键,即我们用布尔表达式a.compareTo(b) == 0来表示“a和b相等吗?”。一般来说,这样的比较都代表这在符号表中的一次成功查找(找到了b)。和排序算法一样,Java为许多经常为键的数据结构提供了标准的compareTo()方法,为你自定义的数据类型实现一个compareTo()方法也不困难。

3.1.2.8 成本模型

无论我们是使用equals()方法(对于符号表的键不是Comparable对象而言)还是Comparable()方法(对于符号表的键是Comparable对象而言),我们使用比较一词来表示将一个符号表条目和一个被查找的键进行比较操作。在大多数的符号表实现中,这个操作都出现在内循环。在少数的例外中,我们则会统计数组的访问次数。

查找的成本模型。在学习符号表的实现时,我们会统计比较的次数(等键性测试或是键的相互比较)。在内循环不进行(极少)的情况下,我们会统计数组的访问次数。

符号表实现的重点在于其中使用的数据结构和get()、put()方法。在用例代码中,除非我们想使用一个特定的实现,我们都是使用ST表示一个符号表实现。


《Algorithms 4th Edition》读书笔记——3.1 符号表(Elementary Symbol Tables)-Ⅱ的更多相关文章

  1. 《Algorithms 4th Edition》读书笔记——3.1 符号表(Elementary Symbol Tables)-Ⅳ

    3.1.4 无序链表中的顺序查找 符号表中使用的数据结构的一个简单选择是链表,每个结点存储一个键值对,如以下代码所示.get()的实现即为遍历链表,用equals()方法比较需被查找的键和每个节点中的 ...

  2. 《Algorithms 4th Edition》读书笔记——3.1 符号表(Elementary Symbol Tables)-Ⅲ

    3.1.3 用例举例 在学习它的实现之前我们还是应该先看看如何使用它.相应的我们这里考察两个用例:一个用来跟踪算法在小规模输入下的行为测试用例和一个来寻找更高效的实现的性能测试用例. 3.1.3.1 ...

  3. 《Algorithms 4th Edition》读书笔记——3.1 符号表(Elementary Symbol Tables)-Ⅰ

    3.1符号表 符号表最主要的目的就是将一个键和一个值联系起来.用例能够将一个键值对插入符号表并希望在之后能够从符号表的所有键值对中按照键值姐找到对应的值.要实现符号表,我们首先要定义其背后的数据结构, ...

  4. 符号表(Symbol Tables)

    小时候我们都翻过词典,现在接触过电脑的人大多数都会用文字处理软件(例如微软的word,附带拼写检查).拼写检查本身也是一个词典,只不过容量比较小.现实生活中有许多词典的应用: 拼写检查 数据库管理应用 ...

  5. C++Primer 4th edition读书笔记-第二章

    1 变量的定义用于为变量分配存储空间,还可以为变量指定初始值.在一个程序中,变量有且只有一个定义.声明用于向程序表明变量的名字和类型.定义也是声明:当定义变量时,我们声明了它的类型和名字.可以通过使用 ...

  6. 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅶ(延伸:堆排序的实现)

    2.4.5 堆排序 我们可以把任意优先队列变成一种排序方法.将所有元素插入一个查找最小元素的有限队列,然后再重复调用删除最小元素的操作来将他们按顺序删去.用无序数组实现的优先队列这么做相当于进行一次插 ...

  7. 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅵ

    · 学后心得体会与部分习题实现 心得体会: 曾经只是了解了优先队列的基本性质,并会调用C++ STL库中的priority_queue以及 java.util.PriorityQueue<E&g ...

  8. 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅴ

    命题Q.对于一个含有N个元素的基于堆叠优先队列,插入元素操作只需要不超过(lgN + 1)次比较,删除最大元素的操作需要不超过2lgN次比较. 证明.由命题P可知,两种操作都需要在根节点和堆底之间移动 ...

  9. 《C++ Primer 4th》读书笔记 序

    注:本系列读书笔记是博主写作于两三年前的,所以是基于<C++ Primer>第四版的,目前该书已更新至第五版,第五版是基于C++11标准的,貌似更新挺多的.博主今年应届硕士毕业,如若过阵子 ...

随机推荐

  1. thinkphp分页时修改last显示标题

    需要修改Page.class.php里lastSuffix为false,这样才能修改last显示标题. 然后就可以设置了 或者直接在方法中声明: $p->lastSuffix = false; ...

  2. c语言结构体数组定义的三种方式

    struct dangdang { ]; ]; ]; int num; int bugnum; ]; ]; double RMB; int dangdang;//成员名可以和类名同名 }ddd[];/ ...

  3. 【转】FLV视频封装格式详解

    Overview Flash Video(简称FLV),是一种流行的网络格式.目前国内外大部分视频分享网站都是采用的这种格式. File Structure 从整个文件上开看,FLV是由The FLV ...

  4. Java IO 概述

    输入和输出-数据源和目标媒介 术语“输入”和“输出”有时候会有一点让人疑惑.一个应用程序的输入往往是另一个应用程序的输出.那么OutputStream流到底是一个输出到目的地的流呢,还是一个产生输出的 ...

  5. (转载)iOS Framework: Introducing MKNetworkKit

    This article is available in Serbo-Croatian,  Japanese and German. (Translations in Serbo-Croatian b ...

  6. AngularJs学习笔记4——四大特性之双向数据绑定

    双向数据绑定 方向1:模型数据(model)绑定到视图(view) 实现方法:①.{{model变量名}}  ②.常用指令(ng-repeat) 方向2:将视图(view)中用户输入的数据绑定到模型数 ...

  7. javascript实现的有缩略图功能的幻灯片切换效果

    不久前写了一个简单的图片效果,没想到那么快就要用到项目中,所以功能方面要丰富一下: 主要改进: 1# 用圆点代替之前简单的页数显示,并且点击圆点可以显示对应图片: 2# 点击圆点,显示对应图片的缩略图 ...

  8. [原创作品] javascript 实现的web分页器原理

    很久没有写博客了,因为最近忙于一些杂七杂八的事情.不过,互联网的价值在于信息共享,因为共享,所以互联网才能飞快发展.博主建了一个技术共享qq群:164858883,因为目前人数还比较少,活跃度还不是很 ...

  9. 多封装,少开放。强烈建议C++标准添加class之间的注入机制

    近日在改动了一下下引擎代码(为了自己的组件),发现有些接口是仅仅有特定类及其内部函数才去訪问,却不使用友元声明的形式进行数据訪问--当然使用了普通非virtual的形式也就是意味着不建议重载. 故此: ...

  10. 学习selenium所须要具备的技术

    学习selenium所须要具备的知识或技术 1.selenium进行的自己主动化測试是基于ui层面的,所以html,css,javascript基本上是不可缺少的,至于javascript,有非常多的 ...