zoukankan      html  css  js  c++  java
  • Trie树

    Trie树即字典树
    以下内容来自某度某科


    在计算机科学中,trie,又称前缀树或字典树,是一种有序树,用于保存关联数组,其中的键通常是字符串。与二叉查找树不同,键不是直接保存在节点中,而是由节点在树中的位置决定。
    在计算机科学中,trie,又称前缀树或字典树,是一种有序树,用于保存关联数组,其中的键通常是字符串。与二叉查找树不同,键不是直接保存在节点中,而是由节点在树中的位置决定。一个节点的所有子孙都有相同的前缀,也就是这个节点对应的字符串,而根节点对应空字符串。一般情况下,不是所有的节点都有对应的值,只有叶子节点和部分内部节点所对应的键才有相关的值。
    Trie这个术语来自于retrieval。根据词源学,trie的发明者Edward Fredkin把它读作英语发音:/ˈtriː/ "tree"。[1][2]但是,其他作者把它读作英语发音:/ˈtraɪ/ "try"。[1][2][3]
    在图示中,键标注在节点中,值标注在节点之下。每一个完整的英文单词对应一个特定的整数。Trie可以看作是一个确定有限状态自动机,尽管边上的符号一般是隐含在分支的顺序中的。
    键不需要被显式地保存在节点中。图示中标注出完整的单词,只是为了演示trie的原理。
    trie中的键通常是字符串,但也可以是其它的结构。trie的算法可以很容易地修改为处理其它结构的有序序列,比如一串数字或者形状的排列。比如,bitwise trie中的键是一串位元,可以用于表示整数或者内存地址。


    关于Trie树是什么,我不会详细的解释(大家可以看一下其他大佬的Blog,不要在意我这个小蒟蒻说的)

    我直接说Trie树的核心:如何建立Trie树

    因为我不喜欢用指针,所以我说的所有内容都不包含指针

    大概论述一下过程:

    1. 选定要加入到Trie树中的字符串
    2. 从根节点开始依次判断当前结点的子节点中是否包含下一个字符
    3. 如果包含,则直接访问,重复第2步
    4. 否则,则建立这个结点,继续重复第2步
    5. 若进行第2步时已经到达了最后一个字符,则直接结束

    以上的内容全是凭着我自己的写法来说的,中间可能会存在错误。可以选择性的跳过上面的概述,直接看例子。


    那么,我们来举个例子
    假如,我要构建成字典树的单词是
    her hen hers say said

    最终构建完的字典树就长这样:

    这里写图片描述




    原谅我图画的丑

    然而我们并不知道这些东西分别代表那些字符串
    于是,我们对每个字符串的结尾所在的那个节点加个标记。

    这里写图片描述

    于是乎,我们从根节点开始,一层层依次遍历,当读入到一个加了标记的结点时,一路读到的字符连成的字符串便是原来需要储存的字符串

    那么,至于怎么加入一个串呀。。。
    我们也来演示一下吧、。。。(画图会画死我的)

    比如当前这样子,其他的串都已经加入,我们现在需要加入字符串said

    这里写图片描述

    那么,我们从根节点开始

    这里写图片描述

    发现根节点的子节点里面存在s这个字符结点

    把一个指针移动过去,继续找接下来的字符

    这里写图片描述

    接着,我们惊奇的发现a也存在了
    于是继续遍历

    这里写图片描述

    这个时候,却发现当前结点不存在一个i结点
    那么,我们就手动的造一个i结点出来

    这里写图片描述

    这个时候,发现有i结点了

    于是继续访问下一层
    这里写图片描述

    发现这一层也没有d结点
    于是我们再人工造一个出来
    并且把它连上去

    这里写图片描述

    然后继续访问下一层。

    这里写图片描述

    还往下继续

    诶~这个串没有了

    OK
    搞定
    标记当前的d结点是一个单词的结束就好了

    这里写图片描述


    上面,我举了一个插入的例子

    而如果要构建整棵Trie树的话,那么就从只有一个根节点开始,反复上面的过程即可。


    画图真是画死我了
    也没有啥东西会让你单独用一个字典树吧。。。
    但是字典树是一个好东西。
    到时候讲其他东西的时候是一定会讲到字典树的
    到时候再说吧


    接下来分析一下Trie树的代码

    struct Node
    {
           bool End;//是否是某个单词的结束
           int vis[MAX];//接下来的子节点的位置
    }Trie[MAXNode};
    

    上面是Trie树节点的构建
    封装在了struct里面
    其中MAX是字符的最大个数
    MAXNode是啥意思就自己理解




    接下来是构建一个Trie树

    void Build(string s)//s是要放到Trie树里面的串
    {
           int now=0;//当前位置
           int l=s.length();//字符串长度
           for(int i=0;i<len;++i)//依次遍历所有位置
           {
                    if(!Trie[now].vis[s[i]])//不存在这个位置
                          Trie[now].vis[s[i]]=++cnt;//那就构建出这个节点
                    now=Trie[now].vis[s[i]];//访问下一层
           }
    }
    


    好了
    差不多了
    (我尽然找不到Trie树的模板题)

    如果文章中有问题,欢迎在评论中告诉我,谢谢。

  • 相关阅读:
    修复TabControl在Binding情况下Canvas被复用的问题
    避免缓加载时因违反惯例导致的空引用!
    乱说一气
    WPF中的数据验证
    [zz]GPU architecture
    [zz]DirectX 11 and Shared Model 5.0
    网页栅格系统中的最佳宽度:960px
    复习html标签及其属性
    去除链接虚线边框css
    使用jquery解决IE6不兼容的伪类
  • 原文地址:https://www.cnblogs.com/cjyyb/p/7196302.html
Copyright © 2011-2022 走看看