执行Trie Tree时出错

时间:2017-01-21 12:56:15

标签: c++ algorithm data-structures hashmap trie

我想插入一个字符串并使用trie数据结构进行搜索操作。这是我使用指针的第一个实现,所以我真的很困惑我在代码中做错了,它给出了编译错误。请帮助调试请告诉我指针逻辑有什么问题。

typedef struct trie {
    unordered_multimap<char, struct trie> child;
    bool isEnd;
} trie;
trie* newtrienode()
{
    trie* newnode = (trie*)malloc(sizeof(trie));
    newnode->isEnd = false;
    return newnode;
}
trie* root = newtrienode();
void insert(string word)
{
    trie* current = root;
    for (int i = 0; i < word.length(); i++) {
        char ch = word[i];
        trie* node = current->child[ch];
        if (node == NULL) {
            trie* node = newtrienode();
            current->child.insert(pair<char, trie>(ch, node));
        }
        current = node;
    }
    current->isEnd = true;
}
bool search(string word)
{
    trie* current = root;
    for (int i = 0; i < word.length(); i++) {
        char ch = word[i];
        trie* node = current->child[ch];
        if (node == NULL) {
            return false;
        }
        current = node;
    }
    return true;
}

1 个答案:

答案 0 :(得分:0)

除了评论中提到的内容外,我发现代码存在一些问题。

1

trie* newnode = (trie*)malloc(sizeof(trie));

这不会创建trie类型的对象,它只会分配大小为trie的内存块,并将指针指向变量newnode。特别是,它不会调用unordered_multimap的构造函数。通过该指针访问child成员会产生未定义的行为。此外,你永远不会释放那段记忆。

2

typedef struct trie {
    unordered_multimap<char, struct trie> child;
    bool isEnd;
} trie;

在第二行,您声明一个unordered_multimap数据成员,其类型不完整trie作为第二个模板参数。有些编译器允许这样做,但标准并不要求它们。另一方面,shared_ptr需要使用不完整类型作为模板参数。此外,一个节点每个字符只能有一个子树,因此您不需要多个映射;一张地图就足够了。因此,我建议使用unordered_map<char, shared_ptr<trie>>并将所有trie*替换为shared_ptr<trie>。在释放root后,它还会处理删除对象。

newtrienode()函数将如下所示:

shared_ptr<trie> newtrienode()
{
    shared_ptr<trie> newnode (new trie());
    newnode->isEnd = false;
    return newnode;
}

3

trie* node = current->child[ch];
if (node == NULL) {
当密钥不存在时,

operator[]不会返回NULL。它将默认构造的对象插入容器并返回对它的引用。要检查密钥是否存在,请使用findcount

4

trie* node = current->child[ch];
if (node == NULL) {
    trie* node = newtrienode();
    current->child.insert(pair<char, trie>(ch, node));
}
current = node;

请注意,在第三行中您要声明一个新变量。在第一行声明的变量node不会被更改。