java trie_java实现Trie树

介绍

Trie树(又名字典树,前缀树)是一种多叉树,是一种专门处理字符串的数据结构,Trie树

示例图如下

ce859697f3c53b9292d67539b56bc11a.png

保存的数据为单词列表[goods,good,gmail,grade,dog,cap,cook,map],应用场景有搜索提示

6bdf65b2da40420e31e0da450ab7c1d0.png

代码实现

import java.util.ArrayList;

import java.util.List;

import java.util.Map;

import java.util.Map.Entry;

import java.util.TreeMap;

import java.util.stream.Collectors;

/**

* 实现Trie树

*/

public class Trie {

/**

* 根节点,不存储数据

*/

private Node root;

public Trie() {

root = new Node(false);

}

/**

* 添加单词

*/

public void add(String word) {

Node cur = root;

char[] array = word.toCharArray();

for (char c : array) {

Map children = cur.children;

children.putIfAbsent(c, new Node(false));

cur = children.get(c);

}

cur.word = true;

}

/**

* 是否包含单词

*/

public boolean contains(String word) {

return contains(word, true);

}

/**

* 是否包含前缀

*/

public boolean prefixContains(String prefix) {

return contains(prefix, false);

}

/**

* 是否匹配单词,支持.匹配任意字符

*/

public boolean match(String word) {

return match(root, word, 0);

}

/**

* 查询所有以prefix为前缀的单词列表

*/

public List commonPrefixSearch(String prefix) {

Node cur = root;

List res = new ArrayList<>();

char[] array = prefix.toCharArray();

for (char c : array) {

Node node = cur.children.get(c);

if (node == null) {

return res;

}

cur = node;

}

commonPrefixSearch(res, new ArrayList<>(), cur);

return res.stream()

.map(x -> prefix + x)

.collect(Collectors.toList());

}

private void commonPrefixSearch(List res, List list, Node root) {

if (root.word) {

char[] arr = new char[list.size()];

for (int i = 0; i < list.size(); i++) {

arr[i] = list.get(i);

}

res.add(new String(arr));

}

//递归加回溯实现

for (Entry entry : root.children.entrySet()) {

list.add(entry.getKey());

commonPrefixSearch(res, list, entry.getValue());

list.remove(list.size() - 1);

}

}

private boolean match(Node root, String word, int index) {

if (index == word.length()) {

return root.word;

}

char c = word.charAt(index);

if (c != '.') {

Node node = root.children.get(c);

return node != null && match(node, word, index + 1);

} else {

//递归加回溯实现

for (Entry entry : root.children.entrySet()) {

if (match(entry.getValue(), word, index + 1)) {

return true;

}

}

return false;

}

}

private boolean contains(String prefix, boolean word) {

Node cur = root;

char[] array = prefix.toCharArray();

for (char c : array) {

Node node = cur.children.get(c);

if (node == null) {

return false;

}

cur = node;

}

if (word) {

return cur.word;

} else {

return true;

}

}

private static class Node {

/**

* 表示当前节点是否是单词

*/

boolean word;

/**

* 孩子节点列表

*/

Map children;

Node(boolean word) {

this.word = word;

children = new TreeMap<>();

}

}

}

添加单词

/**

* 添加单词

*/

public void add(String word) {

Node cur = root;

char[] array = word.toCharArray();

for (char c : array) {

Map children = cur.children;

children.putIfAbsent(c, new Node(false));

cur = children.get(c);

}

cur.word = true;

}

添加good单词,添加之后的树结构为

37b228cb0fbe5962315e8a81da2415fd.png

再添加一个单词gmail

3f9d2eb4a51e4beebdf20d75da069959.png

查找

public class Main {

public static void main(String[] args) {

Trie trie = new Trie();

trie.add("goods");

trie.add("good");

trie.add("google");

trie.add("gmail");

trie.add("grade");

trie.add("gender");

System.out.println(trie.commonPrefixSearch("goo"));

}

}

我们查找以goo为前缀的单词,查询结果为

[good, goods, google]

总结

Trie树在查找字符串公共前缀相关问题时可以有很高的效率。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值