如何为Trie树编写析构函数

时间:2018-03-08 02:21:24

标签: c++ tree destructor trie

我一直致力于一项任务,我们使用trie树将字典中的单词添加到树中,然后搜索它。我坚持的部分是类析构函数。这是我第一次不得不处理析构函数/内存管理,而我在搜索我目前拥有的资源后,下面的内容是我最好的猜测。

我是否在正确的轨道上?每个节点有27个子节点(字母和分隔符),所以我希望它从叶子到根节点都删除它们。

class Trie
{
private:
    TrieNode *_root = nullptr;
    TrieNode *_current = nullptr;
    TrieNode *_child = nullptr;

    string current_word;
    bool setRoot = false;

protected:

public:
    Trie()
    {
        _root = new TrieNode{};
    }

    virtual ~Trie()
    {
        //TODO: clean up memory
        DestroyRecursive(_root);
    }

    void Trie::DestroyRecursive(TrieNode* node)
    {
        if (node != nullptr)
        {
            for (TrieNode* child : node->getChildren())
            {
                delete(child);
            }
        }
    }

如何检查析构函数是否正常工作?我正在使用Visual Studio。

1 个答案:

答案 0 :(得分:0)

您的DestroyRecursive实际上并非递归

您需要在叶节点上调用delete并递归有子节点的节点。

void Trie::DestroyRecursive(TrieNode* node)
{
    if (node != nullptr)
    {
        if (node->getChildren().size() == 0)
        {
            // delete the leaf node
            delete(node);
            return;
        }

        for (TrieNode* child : node->getChildren())
        {
            DestroyRecursive(child);
        }
    }
}

可能出错,具体取决于您对TrieNode结构的依赖性。例如,它是否有一个非平凡的析构函数?

通过将原始指针替换为std::shared_ptr

,可以避免很多这种情况
std::shared_ptr<TrieNode> _root = nullptr;
vector<shared_ptr<TrieNode>> _child = nullptr;

Trie()
{
    _root = std::make_shared<TrieNode>();
}

然后在大多数情况下,您不需要析构函数。超出范围时,std::vectorshared_ptr将负责在适当的内存上调用delete。 请注意,所有权中没有循环依赖性。如果将来添加父指针,则必须是原始指针或std::weak_ptr

  

如何检查析构函数是否正常工作?我正在使用Visual   工作室。

您可以设置breakpoint来检查代码是否被点击。