字典树的实现(Java语言)
通过构建一颗字典树能够实现对多字符串公共前缀的快速查找,以及判断某一字符串是否在一个字典树中;与其他方法相比,该算法的时间复杂度更低,但是查找效率的提高是以空间的占用为代价的。
首先构建一个字典树的节点,定义一个经过该节点次数的int型变量path,一个以当前字符结尾的int型变量end;以及定义拥有26条路径的节点。这里假设构成字典树的所有字符均为小写字母。每个字符均位于各个路径上,并不在每个节点上。
public static class TrieNode
{
public int path; ///定义字符经过节点的次数大小
public int end; ///定义字符的个数大小
public TrieNode[] nexts;
public TrieNode()
{
path = 0;
end = 0;
nexts = new TrieNode[26];假设所有的字符均是以26个小写字母组成的
每个节点后面的路径所表示的字符一定为26个字符中的一个(若存在)
}
}
定义插入一个字符串到字典树中的方法,首先将字符串转换为字符数组的形式,然后求出当前节点后面的路径,若通向下一节点的路径为空,则建出下一个节点;然后将经过当前节点的路径path加1;所有循环结束后,将end变量加1
public void insertOneWord(String word)
{
if(word==null)
{
return;
}
TrieNode node = root;
char[] str = word.toCharArray(); ///将要插入的字符串转换为字符数组的形式
for(int i=0;i<str.length;i++)
{
int index = str[i] - 'a'; ///判断字符串每个字符的索引位置大小
if(node.nexts[index]==null) ///若当前节点不存在,则建出当前节点的下一个节点
{
node.nexts[index] = new TrieNode();
}
node = node.nexts[index];///将当前节点往下移动一个位置
node.path++; ///将当前节点的路径加1,用于之后判断以当前节点结尾的字符串的个数为多少
}
node.end++; ///用于判断一个字符串数组中是否存在输入 的字符串
}
定义删除某个字符串的方法,判断每个节点的path变量是否为空,若为空则表明除了当前字符串外,没有别的字符串经过该路径,因此将通过下一字符的路径赋值为null,从而断开了与之后所有字符的连接,退出当前循环,并且将end–
public void deleteOneWord(String word)
{
if(word==null)
{
return;
}
TrieNode node = root;
char[] str = word.toCharArray();
for(int i=0;i<str.length;i++)
{
int index = str[i] - 'a';
if(--node.nexts[index].path==0) 若当前节点的路径统计为0,说明之后的路径只有当前一条,因此将其赋值为空,直接返回
{
node.nexts[index] = null;
return;
}
node = node.nexts[index];
}
node.end--;
}
之后的判断有多少个字符串在当前构建的字典树中,以及找出有多少个字符串拥有共同的字符前缀的方法,与构建字典树的方法大同小异,这里就不再一一赘述,这里仅附上实现代码
判断共有多少个字符串在字典树中的方法
public int allCharNumber(String word)
{
if(word==null)
{
return 0;
}
TrieNode node = root;
char[] str = word.toCharArray();
for(int i=0;i<str.length;i++)
{
int index = str[i] - 'a';
if(node.nexts[index]==null) ///若当前路径不存在则直接返回
{
return 0;
}
node = node.nexts[index];
}
return node.end; ///否则最终返回end数值
}
判断一共有多少共同字符前缀字符串数量的算法
public int preCommonsCharNumber(String word)
{
if(word==null)
{
return 0;
}
TrieNode node = root;
char[] str = word.toCharArray();
for(int i = 0;i<str.length;i++)
{
int index = str[i] - 'a';
if(node.nexts[index]==null) ///若当前路径为空,则直接返回0,
{
return 0;
}
node = node.nexts[index];
}
return node.path;
}