You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Trie字典树递归遍历中如何存储所有单词到数组且不被覆盖?

问题根因

你每次调用strcpy(storeList, words)都是从storeList数组的首地址写入新单词,后写入的内容必然会覆盖之前已存储的内容。

修改方案

新增一个偏移量参数记录storeList当前可写入的起始位置即可:

  • 给printALLWords函数新增引用传递的偏移量参数,递归过程中修改的偏移量可以全局生效
  • 每次写入单词时从偏移位置开始写入,写入完成后更新偏移量,跳过当前单词的长度和结尾的\0占位
修改后的完整代码
#include <iostream>
#include <cstring>

class TrieNode{
public:
    TrieNode* children[26];
    bool isEndOfWord;
    char letter;

    TrieNode(){
        for(int i = 0; i < 26; i++){
            this->children[i] = NULL;
        }
        this->isEndOfWord = false;
    }
    void insert(TrieNode* root, std::string word){
        for(int i = 0; i < word.size(); i++){
            int index = word[i] - 'a';
            if(root->children[index] == NULL){
                root->children[index] = new TrieNode();
                root->letter = word[i];
            }
            root = root->children[index];
        }
        root->isEndOfWord = true;
    }

    // 新增引用传递的offset参数
    void printALLWords(TrieNode* root, char words[], char storeList[], int level, int& offset){
        if(root->isEndOfWord){
            words[level] = '\0';
            // 从偏移位置开始写入当前单词
            strcpy(storeList + offset, words);
            // 偏移量更新:跳过当前单词长度 + 结尾的\0
            offset += strlen(words) + 1;
            // 不要return,防止漏掉当前节点是中间节点同时也是单词结尾的情况(比如同时存car和card)
        }
        for(int i = 0; i < 26; i++){
            if(root->children[i] != NULL){
                char letter = 'a' + i;
                words[level] = letter;
                printALLWords(root->children[i], words, storeList, level + 1, offset);
            }
        }
    }
};


int main(){
    TrieNode* root = new TrieNode();
    root->insert(root, "car");
    root->insert(root, "cat");

    char words[20];
    char storeList[40];
    int level = 0;
    int offset = 0; // 初始化偏移量为0
    root->printALLWords(root, words, storeList, level, offset);

    // 遍历输出所有单词
    int pos = 0;
    while(pos < offset) {
        std::cout << &storeList[pos] << std::endl;
        pos += strlen(&storeList[pos]) + 1;
    }
    return 0;
}
补充说明

原来的递归终止分支里的return建议注释掉,避免出现当前节点既是某个单词结尾,同时还有子节点的场景下,无法继续遍历子节点的问题(比如你同时插入了car和card,如果保留return就会漏掉card)。

内容的提问来源于stack exchange,提问作者Gero M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 09:06:05