基於Trie樹實現搜索功能

Trie,又稱單詞查找樹或鍵樹,是一種樹形結構。
一組單詞,inn, int, at, age, adv, ant, 我們可以得到下面的Trie。我們目前這個功能主要輸入i就能獲取 到輸入(i,in,inn,int)等同的結果。用這種方式做一下示例:
在這裏插入圖片描述
1、通過list和map來存放想要內容,這種方式的優點在於。在遍歷當前下面子節點的時候,能夠通過hash索引,不用通過去遍歷,速度更快。缺點也是很明顯,map和list的所佔用的空間很大,這種方式也是通過不斷添加子樹。那對於輸入關鍵字前綴不能輸入過長,這會造成整個樹過高。造成空間消耗很大。

public class Trie<T> {
    /**
     * 存儲當前樹的輸出的內容
     */
    private List<T> children;
    /**
     * 存放當前樹下面的子節點樹
     */
    private Map<String, Trie<T>> childMap;

    /**
     * 添加搜索的前綴和想要獲取到的內容
     * @param keys
     * @param t
     */
    public synchronized void add(char[] keys, T t) {
        if (null == children) {
            children = new ArrayList<T>();
        }
        
        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<String, Trie<T>>();
            }
            Trie<T> child = childMap.get(String.valueOf(keys[0]));
            if (null == child) {
                child = new Trie<T>();
            }
            childMap.put(String.valueOf(keys[0]), child);
            child.add(Arrays.copyOfRange(keys, 1, keys.length), t);
        }
    }

    /**
     * 通過輸入前綴 獲取到想要的內容
     * @param keys
     * @return
     */
    public List<T> listAllWords(char[] keys) {
          //遞歸遍歷出口,當遍歷到最後子節點的時候添加的內容
        if (null == keys || keys.length == 0) {
            return children;
        }

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

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

        Trie<T> 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<String> trie = new Trie<>();
        trie.add("中國大慶".toCharArray(), "大慶");
        trie.add("中國青島".toCharArray(), "青島");
        List<String> strLst = trie.listAllWords("中國大".toCharArray());
        System.out.println(strLst);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章