对于一般的Trie树的数据结构,它的实现简单但是空间效率极低。例如,如果要支持26个英文字母,每个节点就要保存26个指针,当数据量继续增大,需要更多的支持内存用量,使得整个数据结构占用内存太多。 由于节点数组中保存挂起的空指针占用了过多内存,我们采用特殊的Trie树的数据结构——Ternary Search Trie,三叉搜索树,它是结合字典树的高时间效率和二叉搜索树的高空间效率的一种数据结构。 三叉搜索树与二叉搜索树不同,键不是直接保存在节点中,而是由节点在树中的位置决定。一个节点的所有子孙都有相同的前缀(prefix),也就是这个节点对应的字符串,而根节点对应空字符串。一般情况下,不是所有的节点都有对应的值,只有叶子节点和部分内部节点所对应的键才有相关的值。 与此同时,三叉搜索树使用了一种聪明的手段去解决字典树的内存问题(空的指针数组)。为了避免多余的指针占用内存,每个节点不再用数组来表示,而是表示成“树中有树”。节点里每个非空指针都会在三叉搜索树里得到属于它自己的节点。 插入字符串的顺序会影响三叉搜索树的结构,为了取得最佳性能,字符串应该以随机的顺序插入到三叉树搜索树中,尤其不应该按字母顺序插入,否则对应于单个Trie节点的子树会退化成链表,极大地增加查找成本。单词的读入顺序对于创建平衡的三叉搜索树很重要,但对于二叉搜索树就不太重要。通过选择一个排序后数据单元集合的中间值,并把它作为开始节点。 三叉搜索树的基本性质可以归纳为: (1)根节点不包含字符,除根节点外的每个节点只包含一个字符。 (2)从根节点到某一个节点,路径上经过的字符连接起来,为该节点对应的字符串。 (3)每个节点的所有子节点包含的字符串不相同。 (4)节点采用“树中有树”的建立方法,避免多余的内存占用。 对于三叉搜索树的实现代码采用C++和Java语言 C++ //向词典树中加入一个单词的过程 privateTSTNodeaddWord(Stringkey){ TSTNodecurrentNode=root;//从树的根节点开始查找 intcharIndex=0;//从词的开头匹配 while(true){ //比较词的当前字符与节点的当前字符 //向词典树中加入一个单词的过程 privateTSTNodeaddWord(Stringkey){ TSTNodecurrentNode=root;//从树的根节点开始查找 intcharIndex=0;//从词的开头匹配 while(true){ //比较词的当前字符与节点的当前字符 intcharComp=key.charAt(charIndex)-currentNode.splitchar; if(charComp==0){//相等 charIndex++; if(charIndex==key.length()){ returncurrentNode; } if(currentNode.eqNode==null){ currentNode.eqNode=newTSTNode(key.charAt (charIndex)); } currentNodecurrentNode=currentNode.eqNode; }elseif(charComp<0){//小于 if(currentNode.loNode==null){ currentNode.loNode=newTSTNode(key.charAt (charIndex)); } currentNodecurrentNode=currentNode.loNode; }else{//大于 if(currentNode.hiNode==null){ currentNode.hiNode=newTSTNode(key.charAt (charIndex)); } currentNodecurrentNode=currentNode.hiNode; } } } intcharComp=key.charAt(charIndex)-currentNode.splitchar; if(charComp==0){//相等 charIndex++; if(charIndex==key.length()){ returncurrentNode; } if(currentNode.eqNode==null){ currentNode.eqNode=newTSTNode(key.charAt (charIndex)); } currentNodecurrentNode=currentNode.eqNode; }elseif(charComp<0){//小于 if(currentNode.loNode==null){ currentNode.loNode=newTSTNode(key.charAt (charIndex)); } currentNodecurrentNode=currentNode.loNode; }else{//大于 if(currentNode.hiNode==null){ currentNode.hiNode=newTSTNode(key.charAt (charIndex)); } currentNodecurrentNode=currentNode.hiNode; } } } Java package sunfa.tree; import java.util.HashMap; import java.util.Iterator; import java.util.Map; public class TernarySearchTrie { public static void main(String args) { Map