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);
}
}