这是我参与2022首次更文挑战的第16天,活动详情查看:2022首次更文挑战。
单词查找树(前序树)
单词查找树(有时被称为前序树)是一种有趣的数据结构。该数据结构多次出现在面试题目中,却在算法教科书中鲜有涉及。
单词查找树是叉树的一种变体,其中每个节点都存储字符。整棵树的每条路径自上而下表示一个单词。
*节点(有时被称为“空节点”)时常被用于指代完整的单词。
例如,如果*节点出现在MANY单词之下,那么MANY则为一个完整的单词。MA路径的出现表示有部分单词是以MA开头的。
- man为一个单词、many、lie、a
*节点在实际实现当中通常被表示为一种特殊的子节点(比如TerminatingTrieNode节点,它继承于TrieNode节点)。或者我们也可以在父节点中使用一个布尔变量terminates来表示单词结束。
单词查找树的节点可以有1至ALPHABET_SIZE + 1个子节点(如果使用布尔变量而不是*节点,则可能有0至ALPHABET_SIZE个子节点)。
通常情况下,单词查找树用于存储整个(英文)语言以便于快速前缀查找。虽然散列表可以快速查找字符串是否是有效的单词,但是它不能识别字符串是否是任何有效单词的前缀。单词查找树则可以很快做到这一点。
到底有多快呢?单词查找树可以在的时间复杂度内检查一个字符串是否是有效前缀,其中是该字符串的长度。这实际上是与散列表有着相同的运行时间复杂度。虽然我们经常认为散列表查询的时间复杂度为,但这并不完全正确。散列表必须读取输入中的所有字符,在单词查找的情况下,其需要的时间。
许多涉及一组有效单词的问题都可以使用单词查找树进行优化。在通过树进行重复性前缀搜索的情况下(例如,查找M,然后MA,然后MAN,然后MANY),我们可以通过传递树中当前节点的引用加以实现。只需检查Y是否是MAN的子节点,而不需要每次都从根节点开始。