菜鳥級Trie樹簡介與簡單實現。。。

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();
    }

輸出結果:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章