基于Trie树实现搜索功能

Trie,又称单词查找树或键树,是一种树形结构。
一组单词,inn, int, at, age, adv, ant, 我们可以得到下面的Trie。我们目前这个功能主要输入i就能获取 到输入(i,in,inn,int)等同的结果。用这种方式做一下示例:
基于Trie树实现搜索功能_第1张图片
1、通过list和map来存放想要内容,这种方式的优点在于。在遍历当前下面子节点的时候,能够通过hash索引,不用通过去遍历,速度更快。缺点也是很明显,map和list的所占用的空间很大,这种方式也是通过不断添加子树。那对于输入关键字前缀不能输入过长,这会造成整个树过高。造成空间消耗很大。

public class Trie {
    /**
     * 存储当前树的输出的内容
     */
    private List children;
    /**
     * 存放当前树下面的子节点树
     */
    private Map> childMap;

    /**
     * 添加搜索的前缀和想要获取到的内容
     * @param keys
     * @param t
     */
    public synchronized void add(char[] keys, T t) {
        if (null == children) {
            children = new ArrayList();
        }
        
        if (null == keys || keys.length == 0) {
            return;
        }
        
        if(!children.contains(t)){
            children.add(t);
        }
        if (keys.length > 0) {
            if (CollectionUtils.isEmpty(childMap)) {
                childMap = new HashMap>();
            }
            Trie child = childMap.get(String.valueOf(keys[0]));
            if (null == child) {
                child = new Trie();
            }
            childMap.put(String.valueOf(keys[0]), child);
            child.add(Arrays.copyOfRange(keys, 1, keys.length), t);
        }
    }

    /**
     * 通过输入前缀 获取到想要的内容
     * @param keys
     * @return
     */
    public List listAllWords(char[] keys) {
          //递归遍历出口,当遍历到最后子节点的时候添加的内容
        if (null == keys || keys.length == 0) {
            return children;
        }

        String currentVertexKey = String.valueOf(keys[0]);

        if (CollectionUtils.isEmpty(childMap)) {
            return null;
        }

        Trie currentTrie = childMap.get(currentVertexKey);
        if (Objects.isNull(currentTrie)) {
            return null;
        }
        //递归遍历子节点的数据
        return currentTrie.listAllWords(Arrays.copyOfRange(keys, 1, keys.length));
    }

    public static void main(String[] args) {
        Trie trie = new Trie<>();
        trie.add("中国大庆".toCharArray(), "大庆");
        trie.add("中国青岛".toCharArray(), "青岛");
        List strLst = trie.listAllWords("中国大".toCharArray());
        System.out.println(strLst);
    }
}

你可能感兴趣的:(数据结构)