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. [置顶] 【cocos2d-x入门实战】微信飞机大战之十三:游戏场景过渡

    原创作品,转载请标明:http://blog.csdn.net/jackystudio/article/details/12082043 游戏是实现了,但是如果有个欢迎界面和一个结束界面就更好了. 欢 ...

  2. (转)iOS7界面设计规范(11) - UI基础 - 图标与图形

    不知别人如何,我自己来讲,平时很习惯很有动力去做的一些事,譬如博客吧,一旦生活中出现一些让自己很难受的状况,就很容易受到影响:像是,你平时所习惯的生活状态都是基于某种东西的,一旦这种东西崩塌,会影响到 ...

  3. Android TextView中实现点击文本超链接(无下划线)的封装类

    android中有的时候须要在TextView上设置一些超链接,点击这些超链接时进行一些操作.比如新浪微博上的一些keyword,点击时会跳转到对应的页面. 怎样实现我们就直接看源代码吧. /** * ...

  4. Swift 新语言开发

    全书文件夹: 一.Welcome to Swift 二.Language Guide 三.Language Reference /* 译者的废话: 几个小时前熬夜看了WWDC,各种激动,今年非常有料啊 ...

  5. 深入浅出理解iOS经常使用的正則表達式—基础篇[Foundation]

    參考资料:cocoachina的zys475481075的文章 几个单词 Regular ['regjʊlə]adj. 定期的:有规律的 Expression[ɪk'spreʃ(ə)n; ek-] n ...

  6. js中indexof()简单使用

    indexOf()方法返回某个指定的字符串值在字符串中首次出现的位置. stringObject.indexOf(searchvalue,fromindex):indexOf()方法对大小写敏感如果要 ...

  7. android 中文件加密 解密 算法实战

    现在项目里面有一个需求,本项目里面下载的视频和文档都不允许通过其他的播放器播放,在培训机构里面这样的需求很多.防止有人交一份钱,把所有的课件就拷给了别人.这样的事情培训机构肯定是不愿意的.现在我项目里 ...

  8. CodeSmith使用总结--调用自定义方法

    上一篇读取了一个表的内容,但是到了真正应用的时候还是不够用的,我们很容易可以对比出来,SQL里边的数据类型的定义和C#中有所不同,比如Saler--String,大写的String在C#中不是一个类型 ...

  9. alt和title的用法区别

    经常用到这两个属性,但是一直没有总结他们的区别.现在我对他们两个的用法做一下总结: 相同点:他们都会飘出一个小浮层,显示文本内容. 不同点: 1.alt只能是元素的属性,而title即可以是元素的属性 ...

  10. 华为Oj 找出字符串第一个出现一次的字符

    #include <stdio.h> #include <string.h> char firstSingle(char *str) { int hash[255]={0}; ...