前缀树的实现

前缀树的实现

何谓前缀树?

前缀树(字典树),使用树状的数据结构存储一个字典的所有单词。前缀树是一个多叉树,一个节点可能有多个子节点,除根结点外,每个节点代表字符串中的一个字符。字符串在前缀树中不一定终止于叶子节点,比如 '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;
    }
};
相关推荐
可均可可7 分钟前
C++之OpenCV入门到提高004:Mat 对象的使用
c++·opencv·mat·imread·imwrite
幸运超级加倍~21 分钟前
软件设计师-上午题-16 算法(4-5分)
笔记·算法
白子寰29 分钟前
【C++打怪之路Lv14】- “多态“篇
开发语言·c++
yannan2019031329 分钟前
【算法】(Python)动态规划
python·算法·动态规划
埃菲尔铁塔_CV算法31 分钟前
人工智能图像算法:开启视觉新时代的钥匙
人工智能·算法
EasyCVR31 分钟前
EHOME视频平台EasyCVR视频融合平台使用OBS进行RTMP推流,WebRTC播放出现抖动、卡顿如何解决?
人工智能·算法·ffmpeg·音视频·webrtc·监控视频接入
linsa_pursuer32 分钟前
快乐数算法
算法·leetcode·职场和发展
小芒果_0134 分钟前
P11229 [CSP-J 2024] 小木棍
c++·算法·信息学奥赛
qq_4340859035 分钟前
Day 52 || 739. 每日温度 、 496.下一个更大元素 I 、503.下一个更大元素II
算法
Beau_Will35 分钟前
ZISUOJ 2024算法基础公选课练习一(2)
算法