📅  最后修改于: 2023-12-03 15:10:49.858000             🧑  作者: Mango
根树(Radix Tree),也叫前缀树(Prefix Tree)或字典树(Trie),是一种基于字符串前缀匹配的高效数据结构。Java中的根树实现主要有两种:基于数组的实现和基于HashMap的实现。
基于数组的实现,其实就是一个内部节点包含着一个固定大小的数组,数组的大小就是字符集的大小,而对于每个字符来说,数组中会存储一个继续下去的子树。因此,查询时也只需一次字符数组寻址即可,效率非常高。但是,由于固定数组的大小,无法支持存储大量不同的字符串。
以下是一个基于数组的根树Java代码片段:
public class ArrayRadixTree {
private final static int CHAR_SIZE = 256;
private RadixTreeNode root;
public void insert(String key) {
if (key == null || key.length() == 0) {
return;
}
char[] charArr = key.toCharArray();
if (root == null) {
root = new RadixTreeNode(false);
}
insert(root, charArr, 0);
}
private void insert(RadixTreeNode node, char[] charArr, int index) {
char c = charArr[index];
if (node.children[c] == null) {
node.children[c] = new RadixTreeNode(false);
}
if (index == charArr.length - 1) {
node.children[c].isEnd = true;
} else {
insert(node.children[c], charArr, index + 1);
}
}
public boolean search(String key) {
if (key == null || key.length() == 0) {
return false;
}
char[] charArr = key.toCharArray();
if (root == null) {
return false;
}
return search(root, charArr, 0);
}
private boolean search(RadixTreeNode node, char[] charArr, int index) {
char c = charArr[index];
if (node.children[c] == null) {
return false;
}
if (index == charArr.length - 1) {
return node.children[c].isEnd;
} else {
return search(node.children[c], charArr, index + 1);
}
}
private static class RadixTreeNode {
boolean isEnd;
RadixTreeNode[] children;
RadixTreeNode(boolean isEnd) {
this.isEnd = isEnd;
this.children = new RadixTreeNode[CHAR_SIZE];
}
}
}
基于HashMap的实现,每个节点不再包含固定大小的数组,而是一个HashMap,存储字符与子节点的对应关系。这种实现方式可支持大量的不同字符串,但是其性能介于基于数组和基于树的实现之间。
以下是一个基于HashMap的根树Java代码片段:
public class MapRadixTree {
private RadixTreeNode root;
public void insert(String key) {
if (key == null || key.length() == 0) {
return;
}
if (root == null) {
root = new RadixTreeNode(false);
}
insert(root, key, 0);
}
private void insert(RadixTreeNode node, String key, int index) {
char c = key.charAt(index);
if (!node.children.containsKey(c)) {
node.children.put(c, new RadixTreeNode(false));
}
if (index == key.length() - 1) {
node.children.get(c).isEnd = true;
} else {
insert(node.children.get(c), key, index + 1);
}
}
public boolean search(String key) {
if (key == null || key.length() == 0) {
return false;
}
if (root == null) {
return false;
}
return search(root, key, 0);
}
private boolean search(RadixTreeNode node, String key, int index) {
char c = key.charAt(index);
if (!node.children.containsKey(c)) {
return false;
}
if (index == key.length() - 1) {
return node.children.get(c).isEnd;
} else {
return search(node.children.get(c), key, index + 1);
}
}
private static class RadixTreeNode {
boolean isEnd;
Map<Character, RadixTreeNode> children;
RadixTreeNode(boolean isEnd) {
this.isEnd = isEnd;
this.children = new HashMap<>();
}
}
}
无论基于数组还是基于HashMap的实现,都提供了高效而有效的方法来存储和查询字符串。开发者可以根据自己的需求选择更适合自己的实现方式。