Trie C++实现

本文介绍了Trie字典树的基本概念、特点及其在字符串检索、词频统计、字符串排序和前缀匹配等方面的应用。此外,还提供了使用C++实现Trie的示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Trie又叫字典树,前缀树等,是一个高效的信息检索数据结构,专门处理字符串匹配。查找和插入字符串的时间复杂都为O(M),M为字符串的长度,空间复杂度为O(ALPHABET_SIZE * key_length * N),N为keys的个数。Trie用空间换时间,利用共同前缀来提高查找效率。

Trie的三个特点:

  • 根节点不包含字符,除根节点外每一个节点都只包含一个字符
  • 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串
  • 每个节点的所有子节点包含的字符都不相同

Trie的应用:

  • 字符串检索
  • 词频统计
  • 字符串排序
  • 前缀匹配

C++实现:

// C++ implementation of search and insert 
// operations on Trie 
#include <bits/stdc++.h> 
using namespace std; 

const int ALPHABET_SIZE = 26; 

// trie node 
struct TrieNode 
{ 
    struct TrieNode *children[ALPHABET_SIZE]; 

    // isEndOfWord is true if the node represents 
    // end of a word 
    bool isEndOfWord; 
}; 

// Returns new trie node (initialized to NULLs) 
struct TrieNode *getNode(void) 
{ 
    struct TrieNode *pNode = new TrieNode; 

    pNode->isEndOfWord = false; 

    for (int i = 0; i < ALPHABET_SIZE; i++) 
        pNode->children[i] = NULL; 

    return pNode; 
} 

// If not present, inserts key into trie 
// If the key is prefix of trie node, just 
// marks leaf node 
void insert(struct TrieNode *root, string key) 
{ 
    struct TrieNode *pCrawl = root; 

    for (int i = 0; i < key.length(); i++) 
    { 
        int index = key[i] - 'a'; 
        if (!pCrawl->children[index]) 
            pCrawl->children[index] = getNode(); 

        pCrawl = pCrawl->children[index]; 
    } 

    // mark last node as leaf 
    pCrawl->isEndOfWord = true; 
} 

// Returns true if key presents in trie, else 
// false 
bool search(struct TrieNode *root, string key) 
{ 
    struct TrieNode *pCrawl = root; 

    for (int i = 0; i < key.length(); i++) 
    { 
        int index = key[i] - 'a'; 
        if (!pCrawl->children[index]) 
            return false; 

        pCrawl = pCrawl->children[index]; 
    } 

    return (pCrawl != NULL && pCrawl->isEndOfWord); 
} 

// Driver 
int main() 
{ 
    // Input keys (use only 'a' through 'z' 
    // and lower case) 
    string keys[] = {"the", "a", "there", 
                    "answer", "any", "by", 
                    "bye", "their" }; 
    int n = sizeof(keys)/sizeof(keys[0]); 

    struct TrieNode *root = getNode(); 

    // Construct trie 
    for (int i = 0; i < n; i++) 
        insert(root, keys[i]); 

    // Search for different keys 
    search(root, "the")? cout << "Yes\n" : 
                        cout << "No\n"; 
    search(root, "these")? cout << "Yes\n" : 
                        cout << "No\n"; 
    return 0; 
} 

 

转载于:https://www.cnblogs.com/betaa/p/11212169.html

### C++实现 Trie 的方法 Trie 是一种用于存储字符串集合的数据结构,也被称为前缀树或字典树。它通过节点表示字符来构建一棵多叉树,从而支持高效的字符串查找操作。 以下是基于引用中的内容以及标准的 Trie 实现方式: #### 1. 节点定义 在 C++ 中,可以使用类 `TrieNode` 来定义 Trie 的节点。每个节点包含两个主要部分: - **子节点指针数组**:通常是一个大小为 26 的数组(假设只处理小写字母),指向其子节点。 - **标志位**:用来标记当前节点是否代表某个单词的结尾。 ```cpp struct TrieNode { TrieNode* children[26]; // 子节点数组 bool isEndOfWord; // 是否为单词结束标志 // 构造函数初始化 TrieNode() : isEndOfWord(false) { for (int i = 0; i < 26; ++i) { children[i] = nullptr; } } }; ``` #### 2. 插入操作 插入一个新单词到 Trie 中涉及遍历该单词的每一个字符,并逐层创建新的节点(如果不存在)。最后,在最后一个字符处设置 `isEndOfWord` 标志。 ```cpp void insert(TrieNode* root, const string& word) { TrieNode* node = root; for (char c : word) { int index = c - 'a'; // 计算字母索引 if (!node->children[index]) { // 如果子节点为空,则新建节点 node->children[index] = new TrieNode(); } node = node->children[index]; } node->isEndOfWord = true; // 设置单词结束标志 } ``` #### 3. 查找操作 给定一个单词,可以通过依次访问对应的子节点来判断是否存在此单词。若某一步发现对应子节点缺失或者到达终点时未找到完整的匹配项,则返回失败;反之则成功。 ```cpp bool search(TrieNode* root, const string& word) { TrieNode* node = root; for (char c : word) { int index = c - 'a'; if (!node->children[index]) { return false; // 若无对应子节点,则直接返回false } node = node->children[index]; } return node && node->isEndOfWord; // 判断是否为有效单词 } ``` #### 4. 前缀查询 类似于查找整个单词的过程,只是不需要验证最终状态下的 `isEndOfWord` 属性即可完成前缀检测功能。 ```cpp bool startsWith(TrieNode* root, const string& prefix) { TrieNode* node = root; for (char c : prefix) { int index = c - 'a'; if (!node->children[index]) { return false; // 发现有不匹配的情况就退出循环并返回false } node = node->children[index]; } return true; // 只要能走到这里说明有这个prefix存在 } ``` 以上即为基本的 Trie 数据结构及其核心功能实现[^1]。 ### 完整代码示例 下面提供了一个简单的完整程序框架供参考: ```cpp #include <iostream> #include <string> using namespace std; // 结构体声明同上... class Trie { public: /** Initialize your data structure here. */ Trie() { root = new TrieNode(); } ~Trie(){ destroy(root); } private: void destroy(TrieNode *current){ for(int i=0;i<26;i++)if(current->children[i]!=NULL)destroy(current->children[i]); delete current; } public: /** Inserts a word into the trie. */ void insert(const string &word) { ::insert(root, word); } /** Returns if the word is in the trie. */ bool search(const string &word) { return ::search(root, word); } /** Returns if there is any word in the trie that starts with the given prefix. */ bool startsWith(const string &prefix) { return ::startsWith(root, prefix); } private: TrieNode* root; }; int main(){ Trie t; t.insert("apple"); cout << t.search("apple") << endl;//true cout << t.startsWith("app")<<endl;//true cout << t.search("app")<<endl;//false return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值