关闭

菜鸟级Trie树简介与简单实现。。。

标签: Trie树字典树
140人阅读 评论(0) 收藏 举报
分类:

Trie树,字典树
又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。

它有3个基本性质:
根节点不包含字符,除根节点外每一个节点都只包含一个字符; 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串; 每个节点的所有子节点包含的字符都不相同。

(以上来自百度百科)

如果我们有一个单词库,然后我们要从里面找词。。。用hash可以很快,但是浪费了很多空间,所以用Trie树,速度一样能到O(n),n是要查找的单词长度。

这就是一颗Trie树,根路径没有值,用#
表示,假如我们的单词库有这么几个单词

    string[] words = new string[] { 
        "ant",
        "at",
        "as",
        "cn",
        "com",
    };

那就对应这么一颗Trie树(来自画图。。。)

从根到叶子节点的值连起来就是一个单词,比如c->o->m,要查找at是否在单词库里,就从第一个字母a开始,找到a节点,下一个字母t,找a节点下是否有t,找到,说明at在,其它单词类似。

构建Trie树和查找过程差不多,代码附上:

//树节点
class TreeNode
{
    public char value = '#';
    public List<TreeNode> next = new List<TreeNode>();
}

class Class1
{
    string[] words = new string[] { 
        "ant",
        "at",
        "as",
        "cn",
        "com",
    };
    //构建Trie树
    public TreeNode Build()
    {
        TreeNode root = new TreeNode();
        //就是不停的添词
        for (int i = 0; i < words.Length; i++)
        {
            AddWord(words[i], root);
        }

        return root;
    }
    //这是主要的方法,把一个词添加到Trie树中
    public void AddWord(string word,TreeNode root)
    {
        TreeNode now = root;
        int i,j;
        for (j = 0; j < word.Length; j++)
        {
            bool has = false;
            char c = word[j];
            for (i = 0; i < now.next.Count; i++)
            {
                if (c == now.next[i].value)
                {
                        now = now.next[i];
                        has = true;
                        break;
                }
            }
            if (!has)
            {
                TreeNode t = new TreeNode();
                t.value = c;
                now.next.Add(t);
                now = now.next[i];
            }
        }
    }
    //查找一个词是否在Trie树中
    public bool Search(TreeNode root,string word)
    {
        TreeNode now = root;
        int i, j;
        for (i = 0; i < word.Length; i++)
        {
            char c = word[i];
            bool has = false;
            for (j = 0; j < now.next.Count; j++)
            {
                if (now.next[j].value == c)
                {
                    now = now.next[j];
                    has = true;
                    break;
                }
            }
            if (!has) return false;
        }
        return true;
    }

}

测试程序:

    static void Main(string[] args)
    {
        Class1 c1 = new Class1();
        TreeNode root=c1.Build();
        Console.WriteLine(c1.Search(root, "cn"));
        Console.WriteLine(c1.Search(root,"cnt"));
        Console.WriteLine(c1.Search(root, "com"));
        Console.WriteLine(c1.Search(root, "at"));
        Console.WriteLine(c1.Search(root, "b"));
        Console.ReadLine();
    }

输出结果:

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:13302次
    • 积分:375
    • 等级:
    • 排名:千里之外
    • 原创:24篇
    • 转载:1篇
    • 译文:0篇
    • 评论:11条
    文章分类
    最新评论