数据结构与算法系列23--Trie树

我们在使用搜索引擎进行搜索时,会发现当我们输入一部分内容后,搜索引擎会弹出很多关键词提示,如果发现有你要查找的内容,你可以直接选中它进行搜索,一定程度上节省了我们的时间。究竟如何实现这种功能呢,它使用的底层数据结构和算法是什么呢?
没错,就是今天要说的Trie树。

Trie树

也叫“字典树”,根据它名称,它本身就是一个树形结构。它是一种专门处理字符串匹配的数据结构,用来解决在一组字符串集合中快速查找字符串的问题。那Trie树究竟有何特殊之处呢,它是通过字符串之间的公共前缀,将重复的前缀合并在一样,并组织成一棵树。
举个例子:
我们现在维护有一个字符串库,里面存放了这样有6个字符串,他们分别是:how,hi,her,hello,so,see。接着我们将这些字符串构造出一个Trie树,如下:(图片来源–极客时间专栏《数据结构与算法之美》)
《数据结构与算法系列23--Trie树》
其中根节点不包含任何信息,每个节点表示一个字符串中的字符,从根节点到红色节点的一条路径表示一个字符串。这样我们就组织好了一棵Trie树,之后每次字符串的查找,都是在这棵Trie树上进行。

实现一个棵Trie树

从前面的图我们知道Trie树是一棵多叉树,在二叉树中,一个节点的左右两个节点是通过指针来储存的,对于多叉树,我们可以借助散列表的思想,我们通过一个下标与字符一一映射的数组,来储存子节点的指针。如下:(图片来源–极客时间专栏《数据结构与算法之美》)
《数据结构与算法系列23--Trie树》
假设我们的字符串中只有从a到z这26个小写字母,我们在数组中下标为0的位置,存储指向子节点a的指针,下标为1的位置存储指向子节点b的指针,以此类推,下标为25的位置,存储的是指向的子节点z的指针。如果某个字符的子节点不存在,我们就在对应的下标的位置存储null。
一个节点的表示如下:

class TrieNode {
  char data;
  TrieNode children[26];
}

查找的时间复杂度

如果要在一组字符串中,频繁地查询某些字符串,用Trie树会非常高效。
每次查询时,如果要查询的字符串长度是k,那我们只需要比对大约k个节点,就能完成查询操作。跟原本那组字符串的长度和个数没有任何关系。所以说,构建好Trie树后,在其中查找字符串的时间复杂度是O(k),k表示要查找的字符串的长度。

Trie 树优缺点

缺点:
字符串中包含的字符集不能太大,否则会非常浪费空间。要求字符串的前缀重合比较多,不然空间消耗会变大很。Trie树中用到了指针,所以,对缓存并不友好,性能上会打个折扣。而且自己实现一个Trie树非常复杂,易出错。像这样,针对在一组字符串中查找字符串的问题,我们在工程中,更倾向于用散列表或者红黑树。因为这两种数据结构,我们都不需要自己去实现,直接利用编程语言中提供的现成类库就行了。但是Trie 树也有自身的优点,虽然它不适合精确匹配查找,这种问题更适合用散列表或者红黑树来解决,但是Trie树比较适合查找前缀匹配的字符串,也就是前面我们讲的在搜索引擎中常见的关键字提醒。Trie 树还可以扩展到更加广泛的一个应用上,就是自动输入补全,比如输入法自动补全功能、IDE+代码编辑器自动补全功能、浏览器网址输入的自动补全功能等等。

    原文作者:Trie树
    原文地址: https://blog.csdn.net/qq_34493908/article/details/86107212
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞