第五章 单词查找树

来源:互联网 发布:现货看盘软件下载 编辑:程序博客网 时间:2024/05/01 04:07
我们可以利用字符串的性质来开发出比第三章更有效的查找算法。本节所讨论的算法有以下性能:
  • 查找命中所需的时间与被查找的键的长度成正比
  • 查找未命中只需检查若干个字符
此处我们可以扩展第三章的符号表的API,添加基于字符的用于处理字符串类型的键的操作。

扩展基于字符的符号表与普通符号表的区别为
  • 将泛型的Key的类型换成了具体的类型String;
  • 添加了3个方法:longestPrefixOf()、keyWithPrefix()和keysThatMatch()。
 5.2.1 单词查找树

数据结构单词查找树:由字符串键中的所有字符构造而成,允许使用被查找键中的字符进行查找。
我们首先描述单词查找树的基本性质,包括查找和插入算法,然后详细学习它的数据表示方法和java实现。

5.2.1.1 基本性质

单词查找树也是由链接的结点组成的数据结构,这些链接可能为空,也可能指向其他结点。每个结点都只可能有一个指向它的结点,称为它的父结点。每个结点都含有R条链接,其中R为字母表的大小。单词查找树一般都含有大量的空链接,因此在绘制一棵单词查找树时一般会忽略空链接。具体来说,我们将每个键所关联的值保存在该键的最后一个字母所对应的的结点中。(值为空的结点在符号表中没有对应的键,它们的存在是为了简化单词查找树中的查找操作。)


5.2.1.2 单词查找树中的查找操作

在单词查找树中查找给定字符串键所对应的值是一个简单的过程,它是以被查找键中的字符为导向的。单词查找树中的每个结点都包含了下一个可能出现的所有字符的链接。从根结点开始,首先经过的是键的首字母所对应的链接;在下一个结点中沿着第二个字符所对应的链接继续前进;在第二个结点中沿着第三个字符所对应的的链接向前,如此这般知道到达键的最后一个字母所指向的结点或是遇到了一条空链接。这可能出现三种情况:
  • 键的尾字符所对应的结点中的值非空。这是一次命中的查找----键所对应的值就是键的尾字符所对应的结点中保存的值。
  • 键的尾字符所对应的结点中的值非空。这是一次未命中的查找-----符号表中不存在被查找的键。
  • 查找结束与一条空链接。这是一次未命中的查找。
在所有的情况中,执行查找的方式就是单词查找树中从根结点开始检查某条路径上的所有结点。

5.2.1.3 单词查找树中的插入操作

和二叉查找树一样,在插入之前要进行一次查找:在单词查找树中意味着沿着被查找的键的所有字符到达树中表示尾字符的结点或者一个空链接。此时可能会出现两种情况。
  • 在到达键的尾字符之前就遇到了一个空链接。在这种情况下,字符查找树中不存在与键的尾字符对应的结点,因此需要为键中还未被检查的每个字符创建一个对应的结点并将键的值保存到最后一个字符的结点中。
  • 在遇到空链接之前就到达了键的尾字符。在这种情况下,和关联数组一样,将该结点的值设为键所对应的的值(无论该值是否为空)。

5.2.1.4 结点的表示
在本节中开头提到过的,我们为单词查找树所绘出的图像和在程序中构造的数据结构并不完全一致,因为我们没有画出空链接。如果考虑空链接的话将会突出单词查找树的以下重要的性质:
  • 每个结点都含有R个链接,对应着每个可能出现的字符;
  • 字符和键均隐式地保存在数据结构中s


5.2.1.5 大小

size()方法的实现有3种显而易见的选择:
  • 即时实现:用一个实例变量N保存键的数量。
  • 更加即时的实现:用结点的实例变量保存子单词查找树中键的数量,在递归的put()和delete()方法调用之后更新它们。
  • 延时递归实现:如上页框注“单词查找树的延时递归方法size()”所示。它会遍历单词查找树中的所有结点并记录非空值的总数。

5.2.1.6 查找所有键
因为字符和键时被隐式地表示在单词查找树中,所以使用用例能够遍历符号表的所有键就变得有些困难。
原创粉丝点击