C#实现字典树

前言

如果有一组字符串{"aaaaab","aaaaac","aaaaad","aaaaa"},需要在其中找到是否存在字符串"aaaaad",如果采用暴力的解法取做,那么将会遍历整个字符数组的所有字符串,那么时间复杂度将会非常的高,当然如果使用字典(哈希表)可以很快找到,那除此之外还有什么办法呢?其它解决方法就是这次要说的字典树。

原理

通过观察,在判断是否存在字符时,字符串数组中的字符串都有同样的前缀,而在查找是否存在目标字符时多次遍历了同样的前缀,因为这个原因大大的提升了时间复杂度,而字典树就是解决这个问题,他将同样字符串相同前缀的部分共有同一个遍历路径,这样可以一次性遍历多个字符串的相同前缀部分,不同的地方在以分叉的形式继续向下遍历,直到找到结果。这种形式便把所有字符构建成了一棵树。

C#实现字典树_第1张图片

带菱形的节点说明为一个字符串。

代码 

TrieContainer的Add方法就是构建字典树,Contians方法判断字符是否存在。

public class TrieContainer
    {
        public Trie root;

        public TrieContainer()
        {
            root = new Trie();
        }

        public TrieContainer(IEnumerable str) : this()
        {
            foreach (var item in str)
                Add(item);
        }

        public void Add(string s)
        {
            Trie cur = root;
            foreach (var item in s)
            {
                if (!cur.children.ContainsKey(item))
                    cur.children.Add(item, new Trie());
                cur = cur.children[item];
            }
            cur.isEnd = true;
        }

        public bool Contains(string s)
        {
            Trie cur = root;
            int index = 0;
            foreach (var item in s)
            {
                if (!cur.children.ContainsKey(item))
                    return false;
                cur = cur.children[item];
                index++;
            }
            return cur.isEnd;
        }
    }

    public class Trie
    {
        public Dictionary children;
        public bool isEnd;
        public Trie()
        {
            children = new Dictionary();
        }
    }

这里我把构建字典树单独作为了一个类,实际上更多时候都是对trie节点进行操作,而不是当初判断字符串是否存在。例如648. 单词替换 - 力扣(LeetCode)。

你可能感兴趣的:(C#,数据结构,字典树,c#,数据结构)