`
m2000hsf
  • 浏览: 99628 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

三叉Trie树

 
阅读更多
在一个三叉搜索树(Ternary Search Trie)中,每一个节点包括一个字符,但和数字搜索树不同,三叉搜索树只有三个指针:一个指向左边的树;一个指向右边的树;还有一个向下,指向单词的下一个数据单元。三叉搜索树是二叉搜索树和数字搜索树的混合体。它有和数字搜索树差不多的速度但是和二叉搜索树一样只需要相对较少的内存空间。

树是否平衡取决于单词的读入顺序。如果按排序后的顺序插入,则生成方式最不平衡。单词的读入顺序对于创建平衡的三叉搜索树很重要,但对于二叉搜索树就不太重要。通过选择一个排序后数据单元集合的中间值,并把它作为开始节点,我们可以创建一个平衡的三叉树。可以写一个专门的过程来生成平衡的三叉树词典。

   
/**  
     * 在调用此方法前,先把词典数组k排好序  
     * @param fp 写入的平衡序的词典  
     * @param k 排好序的词典数组  
     * @param offset 偏移量  
     * @param n 长度  
     * @throws Exception  
     */  
    void outputBalanced(BufferedWriter fp,ArrayList<String> k,int offset,   
    int n){  
        int m;  
        if (n < 1) {  
            return;  
        }  
        m = n >> 1; //m=n/2  
          
        String item= k.get(m + offset);  
     
        fp.write(item);//把词条写入到文件  
        fp.write('\n');  
          
        outputBalanced(fp,k,offset, m); //输出左半部分  
        outputBalanced(fp,k, offset + m + 1, n - m - 1); //输出右半部分  
    }
 
取得平衡的单词排序类似于洗扑克牌。假想有若干张扑克牌,每张牌对应一个单词,先把牌排好序,然后取最中间的一张牌,单独放着。剩下的牌分成了两摞,左边一摞牌中也取最中间的一张放在取出来的那张牌后面。右边一摞牌中也取最中间的一张放在取出来的牌后面,以此类推。

我们再次以有序的数据单元(as  at  be  by  he  in  is  it  of  on  or  to)为例。 首先我们把关键字"is"作为中间值并且构建一个包含字母"i"的根节点。它的直接后继节点包含字母"s"并且可以存储任何与"is"有关联的数据。对于"i"的左树,我们选择"be"作为中间值并且创建一个包含字母"b"的节点,字母"b"的直接后继节点包含"e"。该数据存储在"e"节点。对于"i"的右树,按照逻辑,选择"on"作为中间值,并且创建"o"节点以及它的直接后继节点"n"。

TernarySearchTrie本身存储关键字到值的对应关系,可以当做HashMap对象来使用。关键字按照字符拆分成许多节点,以TSTNode的实例存在。值存储在TSTNode的data属性中。TSTNode的实现代码如下所示:
   
public final class TSTNode {  
            /**  节点的值  */  
            public Data data=null;// data属性可以存储
    词原文和词性、词频等相关的信息  
              
            protected TSTNode loNode; //左边节点  
            protected TSTNode eqNode; //中间节点  
            protected TSTNode hiNode; //右边节点  
              
            protected char splitchar; // 本节点表示的字符  
            /**  
             *  构造方法  
             *  
             *@param  splitchar  该节点表示的字符  
             */  
            protected TSTNode(char splitchar) {  
                this.splitchar = splitchar;  
            }  
            public String toString()    {  
                return "splitchar:"+ splitchar;  
            }  
    }
 

查找词典的基本过程是:输入一个词,返回这个词对应的TSTNode对象,如果该词不在词典中则返回空。在查找词典的过程中,从树的根节点匹配Key,按Char从前往后匹配Key。charIndex表示Key当前要比较的Char的位置。匹配过程如下所示:
   
protected TSTNode getNode(String key, TSTNode startNode) {  
            if (key == null ) {  
                return null;  
            }  
            int len = key.length();  
            if (len ==0)  
                return null;  
            TSTNode currentNode = startNode; //匹配过程中当前节点的位置  
            int charIndex = 0;  
            char cmpChar = key.charAt(charIndex);  
            int charComp;  
            while (true) {  
                if (currentNode == null) {//没找到  
                    return null;  
                }  
                charComp = cmpChar - currentNode.splitchar;  
                if (charComp == 0) {//相等  
                    charIndex++;  
                    if (charIndex == len) {//找到了  
                        return currentNode;  
                    }  
                    else {  
                        cmpChar = key.charAt(charIndex);  
                    }  
                    currentNodecurrentNode = currentNode.eqNode;  
                } else if (charComp < 0) {//小于  
                    currentNodecurrentNode = currentNode.loNode;  
                } else {//大于  
                    currentNodecurrentNode = currentNode.hiNode;  
                }  
            }  
    }
 

三叉树的创建过程也就是在Trie树上创建和单词对应的节点。实现代码如下所示:
   
//向词典树中加入一个单词的过程  
    private TSTNode addWord(String key) {  
            TSTNode currentNode = root; //从树的根节点开始查找  
            int charIndex = 0; //从词的开头匹配  
            while (true) {  
                //比较词的当前字符与节点的当前字符  
                int charComp =key.charAt(charIndex) - 
    currentNode.splitchar;   
                if (charComp == 0) {//相等  
                    charIndex++;  
                    if (charIndex == key.length()) {  
                        return currentNode;  
                    }  
                    if (currentNode.eqNode == null) {  
                        currentNode.eqNode = new TSTNode(key.charAt  
                    (charIndex));  
                    }  
                    currentNodecurrentNode = currentNode.eqNode;  
                } else if (charComp < 0) {//小于  
                    if (currentNode.loNode == null) {  
                        currentNode.loNode =    new TSTNode(key.charAt  
                    (charIndex));  
                    }  
                    currentNodecurrentNode = currentNode.loNode;  
                } else {//大于  
                    if (currentNode.hiNode == null) {  
                        currentNode.hiNode =    new TSTNode(key.charAt  
                    (charIndex));  
                    }  
                    currentNodecurrentNode = currentNode.hiNode;  
                }  
            }  
    }
 
相对于查找过程,创建过程在搜索过程中判断出链接的空值后创建相关的节点,而不是碰到空值后结束搜索过程并返回空值。

同一个词可以有不同的词性,例如"朝阳"既可能是一个"区",也可能是一个"市"。可以把这些和某个词的词性相关的信息放在同一个链表中。这个链表可以存储在TSTNode 的Data属性中。
0
1
分享到:
评论

相关推荐

    C#编写的三叉Trie树

    对于一般的Trie树的数据结构,它的实现简单但是空间效率极低。三叉搜索树使用了一种聪明的手段去解决字典树的内存问题(空的指针数组)。为了避免多余的指针占用内存,每个节点不再用数组来表示,而是表示成“树中有...

    基于三叉树的中文字典结构

    三叉树,又称为Trie或Prefix Tree,是一种有序树数据结构,它能有效存储和查找具有公共前缀的字符串。与二叉搜索树不同,三叉树每个节点通常有三个子节点,分别代表字符集中的三个不同字符。这样的设计使得三叉树在...

    搜索引擎核心技术与实现

    - **查找词典算法**:包括标准Trie树和三叉Trie树的算法。 - **中文分词的原理与流程**:解释了全切分词图的保存和形成,以及基于概率语言模型和N元分词方法的分词技术。 - **语料库与新词发现**:讨论了如何建立...

    解密搜索引擎技术实战:Lucene&Java精华版

    - **4.2.2 三叉Trie树**:介绍了三叉Trie树的特点及其优势。 - **4.3 中文分词的原理**:详细介绍了中文分词的基本原理和技术背景。 - **4.4 中文分词流程与结构**:讲解了中文分词的一般流程及结构设计。 - **4.5 ...

    AC-TernarySearchTrie

    它基于有限状态自动机(FSA)的概念,通过构建一种特殊的自动机——三叉搜索树(Ternary Search Trie,TST),来实现对大量模式串的并行查找。在AC自动机中,每个节点不仅包含当前字符的信息,还存储了前缀指向的...

    生锈的三元搜索树集合,并尽可能使用与std :: collections类似的API。-Rust开发

    三元搜索树是trie的一种类型(有时称为前缀树),其中将节点排列在其中一种类似于二叉搜索树的方式,但是最多具有三个子级,而不是二叉树的限制,与其他前缀树一样,三叉搜索树可以用作关联映射结构,并具有增量字符...

    Java数据结构与算法源代码

    a.10 个数据结构:数组,链表,栈,队列,散列表,三叉树,堆,跳表图,Trie 树。 b.10 个算法:递归,排序,二分查找,搜索,哈希算法,贪心算法,分治算法,回溯算法,动态规划,字符串匹配算法。 四。学习技巧 ...

    同学录管理系统.rar

    系统还可能包含搜索功能,这可能涉及到模糊匹配和排序算法,如Trie树(字典树)用于快速查找类似姓名,或者快速排序和归并排序用于对学友信息进行排序。 最后,为了便于用户界面的交互,可能还会涉及到数据库技术,...

    数据结构算法实现(严蔚敏版配套实现程序)

    范例1-100 按关键字符串遍历Trie树 301 ∷相关函数:SearchTrie函数 1.6.8 哈希表的基本操作 306 范例1-101 哈希表的基本操作 306 ∷相关函数:SearchHash函数 1.7 图 311 1.7.1 图的邻接矩阵存储表示 311 范例1-102...

    数据结构 严蔚敏 代码

    范例1-100 按关键字符串遍历Trie树 301 ∷相关函数:SearchTrie函数 1.6.8 哈希表的基本操作 306 范例1-101 哈希表的基本操作 306 ∷相关函数:SearchHash函数 1.7 图 311 1.7.1 图的邻接矩阵存储表示 311 范例1-102...

    数据结构(王)c元代码

    范例1-100 按关键字符串遍历Trie树 301 ∷相关函数:SearchTrie函数 1.6.8 哈希表的基本操作 306 范例1-101 哈希表的基本操作 306 ∷相关函数:SearchHash函数 1.7 图 311 1.7.1 图的邻接矩阵存储表示 311 范例1-102...

    数据结构算法实现(严蔚敏版配套实现程序)

    范例1-100 按关键字符串遍历Trie树 301 ∷相关函数:SearchTrie函数 1.6.8 哈希表的基本操作 306 范例1-101 哈希表的基本操作 306 ∷相关函数:SearchHash函数 1.7 图 311 1.7.1 图的邻接矩阵存储表示 311 范例1-102...

    Nginx服务器中location配置的一些基本要点解析

    对于字符串匹配,Nginx采用了一种高效的三叉字符串排序树(Trie树)结构,以快速找到最匹配的`location`。这种数据结构在构建时就考虑到了平衡性,从而确保了高效查找。 字符串匹配的`location`类型有以下几种: 1...

    nginx 配置location匹配规则实例讲解

    Nginx为了提高匹配效率,对字符串匹配的`location`采用了三叉字符串排序树(Trie树)的数据结构。这种方式使得搜索效率更高,尤其是在大量`location`配置的情况下。 为了更好地理解和应用这些规则,以下是一些实用...

    C语言通用范例开发金典.part2.rar

    范例1-100 按关键字符串遍历Trie树 301 ∷相关函数:SearchTrie函数 1.6.8 哈希表的基本操作 306 范例1-101 哈希表的基本操作 306 ∷相关函数:SearchHash函数 1.7 图 311 1.7.1 图的邻接矩阵存储表示 311 ...

    C语言通用范例开发金典.part1.rar

    范例1-100 按关键字符串遍历Trie树 301 ∷相关函数:SearchTrie函数 1.6.8 哈希表的基本操作 306 范例1-101 哈希表的基本操作 306 ∷相关函数:SearchHash函数 1.7 图 311 1.7.1 图的邻接矩阵存储表示 311 ...

    C 开发金典

    范例1-100 按关键字符串遍历Trie树 301 ∷相关函数:SearchTrie函数 1.6.8 哈希表的基本操作 306 范例1-101 哈希表的基本操作 306 ∷相关函数:SearchHash函数 1.7 图 311 1.7.1 图的邻接矩阵存储表示 311 ...

Global site tag (gtag.js) - Google Analytics