今天这篇文章源于上周在工作中解决的一个实际问题,它是个比较普遍的问题,无论做什么开发,估计都有遇到过。具体是这样的,我们有一份高校的名单(2657个),需要从海量的文章标题中找到包含这些高校的标题,其实就是模糊查询。(关注公众号 渡码,回复关键词 trie 获取完整源代码)对应的伪代码如下
selected_titles = []
for 标题 in 海量标题:
for 高校 in 高校名单:
if 标题.contains(高校):
selected_titles.add(标题)
break
如果是大数据开发,对应的SQL的伪代码是这样的
select title
from tb
where
title rlike '清华大学|北京大学|...2657个高校'
上面这两种做法都能实现我们的需求,但它们的共同问题是查询效率太低。如果我们要匹配的高校不是2657个而是几十万甚至上百万,那这种方式耗费时之久是不可想象的。
优化这类问题通常需要在数据结构上做文章,这个问题中我们能优化的数据结构也只有“高校名单”这个了,上面的伪代码中我们存放“高校名单”的数据结构是数组,当我们查找某个title是否包含某个高校的时候,需要从头到尾遍历一遍“高校名单”,并且名单越长,遍历耗时就越长。
清楚了数组这种数据结构的缺点后,接下来我们重点要做的就是寻找一个数据结构可以做到在不遍历整个“高校名单”的情况下就可以完成模糊查询。这个数据结构就是我们今天要介绍的 Trie 树,冷眼一看这个单词有点陌生,又是一个树型结构,感觉会很复杂似的,实际上这个数据结构的设计思想非常简单,一学就会。
下面我们就来学习一下 Trie 树。为了方面讲解,假设“高校名单”里只有下面5个元素
ABC、ABD、BCD、BCE、C、CAB、CDE
对应的两种数据结构如下: