算法与数据结构:字典树

题目来源:020711 每日1题:#676 实现一个魔法字典#208 实现Trie(前缀树)

字典树基本描述

        Trie/ Prefix Tree,一般指字典树或者前缀树。在有基本数据结构二叉树概念的基础上,简单理解为多叉树。以一般题目的26小写字母编码为例,即26叉树。

        事实上,搭建Trie远不如构造一个AVL复杂;相比基本的二叉树,因为Trie的应用目标很明晰,所以操作花样也不必二叉树繁多。所以,有了基本数据结构的基础,理解为先,代码实现倒并不会更难。

字典树的实现

二维数组实现

        我先是读了一种二维数组构建的代码,可能有的人会觉得,那种写法敲起来比较快;当然相应的代价,要做预分配数组的空间估计,而往往过估计会带来内存开销。好处按博文介绍是,相对标准实现形式,省去new每个新节点的时间开销。

推荐阅读:宫水三叶的字典树入门

        我是直接按顺序读的,先读代码会有点gap. 拉倒最后有些介绍其实挺清晰的了。我这里记录一个关键的点:index表观上记录了最新开辟的第n个结点编号;事实上,它有两层内涵:

1.因为是模拟树结构,每个结点时有后继的。编号为index的结点后继,将在trie[index][]这一行开辟新的空间。

2.也因此,index其实是二维数组大小的一个衡量。一般来说,先对二位数组估计;通常预留足够大,但如果遇到极端情形,也是可以通过index越界而预知,从而对数组空间重分配。

trieNode实现

我个人感觉敲起来也很快。

值得指出的一个点是,在单词插入字典完成后,需要在最后的节点上打上flag. 这个操作在判断前缀时是不需要的;但要做完全匹配,需要用它来判断单词完结。

class Trie {
public:
    Trie() : isEnd(0), tns(26, nullptr) {
    }

    void insert(string word) {
        Trie* node = this;
        for (auto& i : word) {
            if (node -> tns[i - 'a'] == nullptr)    node -> tns[i - 'a'] = new Trie();
            node = node->tns[i - 'a'];
        }
        node->isEnd = 1;
    }

    bool search(string word);

    bool startsWith(string prefix);
private:
    bool isEnd;
    std::vector<Trie*> tns;
};

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值