前缀树的实现

前缀树的实现

何谓前缀树?

前缀树(字典树),使用树状的数据结构存储一个字典的所有单词。前缀树是一个多叉树,一个节点可能有多个子节点,除根结点外,每个节点代表字符串中的一个字符。字符串在前缀树中不一定终止于叶子节点,比如 'app'。如果前缀树路径到达某个节点时表示了一个完整的字符串,那么这个节点应有特殊的标识。一个存储字符串 "apple" "apply" "app" "huw" "oppo" "xiao" "mi" 的前缀树如图:

实现前缀树

实现一个前缀树 Trie ,它有下列操作:

  1. 函数 insert ,在前缀树中添加一个字符串
  2. 函数 search,查找字符串,如果前缀树中包含该字符串则返回 true,否则返回 false。
  3. 函数 startWith,查找字符串前缀。

节点的选择

子节点容器可以选择使用哈希表或数组。

  • 在字符集大小固定且较小的情况下,数组可以提供紧凑的存储,没有额外的哈希表开销。数组可以保持元素有序性以及空间效率比较高。
  • 哈希表比较灵活。

真实的结构:

cpp 复制代码
class TrieNode {
public:
	std::unordered_map<char, TrieNode*> children;
	bool id_end_of_word;
	
	TrieNode() : is_end_of_word(false) {}
};

插入

cpp 复制代码
 void insert(const std::string& word) {
     TrieNode* node = root;
     for (char ch : word) {
         if (node->children.find(ch) == node->children.end()) {
             node->children[ch] = new TrieNode();
         }
         node = node->children[ch];
     }
     node->isEndOfWord = true;
 }

查找

cpp 复制代码
bool search(const std::string& word) {
	TrieNode* node = root;
	for (const auto& ch : word) {
		if (node->children.find(ch) == node->children.end()) return false;
		node = node->children[ch];
	}
	return node->is_end_of_word;
}

查找前缀

查找前缀与查找差别在于:可以直接返回 true。

cpp 复制代码
bool startWith(const std::string& word) {
	TrieNode* node = root;
	for (const auto& ch : word) {
		if (node->children.find(ch) == node->children.end()) return false;
		node = node->children[ch];
	}
	return true;
}

完整代码

cpp 复制代码
class Trie {
private:
    TrieNode* root;
    
public:
    Trie() {
        root = new TrieNode();
    }
    
    void insert(const std::string& word) {
        TrieNode* node = root;
        for (char ch : word) {
            if (node->children.find(ch) == node->children.end()) {
                node->children[ch] = new TrieNode();
            }
            node = node->children[ch];
        }
        node->isEndOfWord = true;
    }
    
    bool search(const std::string& word) const {
        TrieNode* node = root;
        for (char ch : word) {
            if (node->children.find(ch) == node->children.end()) {
                return false;
            }
            node = node->children[ch];
        }
        return node->isEndOfWord;
    }
};
相关推荐
大数据张老师2 小时前
数据结构——邻接矩阵
数据结构·算法
低音钢琴3 小时前
【人工智能系列:机器学习学习和进阶01】机器学习初学者指南:理解核心算法与应用
人工智能·算法·机器学习
旭意3 小时前
C++蓝桥杯之结构体10.15
开发语言·c++
深思慎考4 小时前
调用百度云语音识别服务——实现c++接口识别语音
c++·语音识别·百度云
傻童:CPU5 小时前
C语言需要掌握的基础知识点之前缀和
java·c语言·算法
深思慎考5 小时前
从合并两个链表到 K 个链表:分治思想的递进与堆优化
数据结构·链表·递归··队列·合并链表
又见野草5 小时前
软件设计师知识点总结:数据结构与算法(超级详细)
数据结构·算法·排序算法
GalaxyPokemon5 小时前
有一个服务器,用于提供HTTP服务,但是需要限制每个用户在任意的100秒内只能请求60次,怎么实现这个功能
算法
fl1768316 小时前
基于opencv+Mediapipe+CNN实现用手势识别控制对鼠标操控python源码+项目说明+设计文档
算法
K 旺仔小馒头6 小时前
优选算法:01 双指针巧解移动零问题
c++·算法·刷题