C++ 释放内存二叉树

C++ 释放内存二叉树,c++,binary-tree,huffman-code,C++,Binary Tree,Huffman Code,我有一个创建二叉树(*build_tree)*(Huffman)的函数 我还需要一个函数来释放构建树所分配的内存 这是我第一次使用二叉树,所以我有点困惑。 我应该创建一个循环来遍历树中的每个节点并删除它吗? 我应该考虑节点是叶子还是父节点? void free_memory(NodePtr root) { delete root; } struct HuffmanNode { //some stuff HuffmanNode *left; HuffmanNode

我有一个创建二叉树(*build_tree)*(Huffman)的函数

我还需要一个函数来释放构建树所分配的内存

这是我第一次使用二叉树,所以我有点困惑。 我应该创建一个循环来遍历树中的每个节点并删除它吗? 我应该考虑节点是叶子还是父节点?

void free_memory(NodePtr root)
{
    delete root;
}

struct HuffmanNode
{
   //some stuff
    HuffmanNode *left;
    HuffmanNode *right;
};

如果有人能帮我开始,我将不胜感激:)

如果你使用智能指针,问题就会自行解决。如果每个节点包含其子节点的专用SP,并且您删除了一个节点,则其所有子节点也将被释放。显然,您的类析构函数(在清理时将被SP调用)需要释放任何其他非RIIA分配的资源(如果存在)

class Node
{
private:
   std:unique_ptr<Node> left;
   std:unique_ptr<Node> right;
}
您还可以按照@OldProgrammer的建议执行操作,并在执行过程中从下到上遍历树以删除节点。记住,你必须自下而上做这件事。如果自上而下执行此操作,则会丢失对(尚未)未删除的子节点的引用并泄漏内存。正如您所看到的,递归删除()的代码要复杂得多

递归地做(任何事情)都有内存开销。请参阅:。如果你的树很大,那么你应该考虑这个问题并相应地进行测试。
如果您可以使用SP,我建议您使用第一种解决方案。

如果您使用智能指针,问题将自行解决。如果每个节点包含其子节点的专用SP,并且您删除了一个节点,则其所有子节点也将被释放。显然,您的类析构函数(在清理时将被SP调用)需要释放任何其他非RIIA分配的资源(如果存在)

class Node
{
private:
   std:unique_ptr<Node> left;
   std:unique_ptr<Node> right;
}
您还可以按照@OldProgrammer的建议执行操作,并在执行过程中从下到上遍历树以删除节点。记住,你必须自下而上做这件事。如果自上而下执行此操作,则会丢失对(尚未)未删除的子节点的引用并泄漏内存。正如您所看到的,递归删除()的代码要复杂得多

递归地做(任何事情)都有内存开销。请参阅:。如果你的树很大,那么你应该考虑这个问题并相应地进行测试。
如果您同意使用SP,我建议您使用第一种解决方案。

如果您在流程步骤中实施订单后树遍历并删除节点和数据,您将确保访问树的每个节点并删除数据

您可以看到一个递归和迭代示例,其中包含下面复制的相关代码

递归解决方案:

void postOrderTraversal(BinaryTree *p) {    
    if (!p) return;
        postOrderTraversal(p->left);
        postOrderTraversal(p->right);

        // this is where we delete
        delete p->data;
        delete p;
    }
void postOrderTraversalIterative(BinaryTree *root) {
    if (!root) return;
    stack<BinaryTree*> s;
    s.push(root);
    BinaryTree *prev = NULL;
    while (!s.empty()) {
        BinaryTree *curr = s.top();
        if (!prev || prev->left == curr || prev->right == curr) {
            if (curr->left)
                s.push(curr->left);
            else if (curr->right)
                s.push(curr->right);
        } else if (curr->left == prev) {
            if (curr->right)
                s.push(curr->right);
        } else {
            // this is where we delete
            delete curr->data;
            delete curr;
            s.pop();
        }
        prev = curr;
    }
}
一种可能的迭代解决方案:

void postOrderTraversal(BinaryTree *p) {    
    if (!p) return;
        postOrderTraversal(p->left);
        postOrderTraversal(p->right);

        // this is where we delete
        delete p->data;
        delete p;
    }
void postOrderTraversalIterative(BinaryTree *root) {
    if (!root) return;
    stack<BinaryTree*> s;
    s.push(root);
    BinaryTree *prev = NULL;
    while (!s.empty()) {
        BinaryTree *curr = s.top();
        if (!prev || prev->left == curr || prev->right == curr) {
            if (curr->left)
                s.push(curr->left);
            else if (curr->right)
                s.push(curr->right);
        } else if (curr->left == prev) {
            if (curr->right)
                s.push(curr->right);
        } else {
            // this is where we delete
            delete curr->data;
            delete curr;
            s.pop();
        }
        prev = curr;
    }
}
void postOrderTraversalIterative(二进制树*根){
如果(!root)返回;
堆栈s;
s、 推(根);
BinaryTree*prev=NULL;
而(!s.empty()){
二进制树*curr=s.top();
如果(!prev | | prev->left==curr | | prev->right==curr){
如果(当前->左)
s、 按(当前->左);
否则如果(当前->右侧)
s、 推送(当前->右侧);
}否则如果(当前->左==上一个){
如果(当前->右侧)
s、 推送(当前->右侧);
}否则{
//这就是我们删除的地方
删除当前->数据;
删除curr;
s、 pop();
}
上一次=当前;
}
}

如果在流程步骤中执行订单后树遍历并删除节点和数据,则将确保访问树的每个节点并删除数据

您可以看到一个递归和迭代示例,其中包含下面复制的相关代码

递归解决方案:

void postOrderTraversal(BinaryTree *p) {    
    if (!p) return;
        postOrderTraversal(p->left);
        postOrderTraversal(p->right);

        // this is where we delete
        delete p->data;
        delete p;
    }
void postOrderTraversalIterative(BinaryTree *root) {
    if (!root) return;
    stack<BinaryTree*> s;
    s.push(root);
    BinaryTree *prev = NULL;
    while (!s.empty()) {
        BinaryTree *curr = s.top();
        if (!prev || prev->left == curr || prev->right == curr) {
            if (curr->left)
                s.push(curr->left);
            else if (curr->right)
                s.push(curr->right);
        } else if (curr->left == prev) {
            if (curr->right)
                s.push(curr->right);
        } else {
            // this is where we delete
            delete curr->data;
            delete curr;
            s.pop();
        }
        prev = curr;
    }
}
一种可能的迭代解决方案:

void postOrderTraversal(BinaryTree *p) {    
    if (!p) return;
        postOrderTraversal(p->left);
        postOrderTraversal(p->right);

        // this is where we delete
        delete p->data;
        delete p;
    }
void postOrderTraversalIterative(BinaryTree *root) {
    if (!root) return;
    stack<BinaryTree*> s;
    s.push(root);
    BinaryTree *prev = NULL;
    while (!s.empty()) {
        BinaryTree *curr = s.top();
        if (!prev || prev->left == curr || prev->right == curr) {
            if (curr->left)
                s.push(curr->left);
            else if (curr->right)
                s.push(curr->right);
        } else if (curr->left == prev) {
            if (curr->right)
                s.push(curr->right);
        } else {
            // this is where we delete
            delete curr->data;
            delete curr;
            s.pop();
        }
        prev = curr;
    }
}
void postOrderTraversalIterative(二进制树*根){
如果(!root)返回;
堆栈s;
s、 推(根);
BinaryTree*prev=NULL;
而(!s.empty()){
二进制树*curr=s.top();
如果(!prev | | prev->left==curr | | prev->right==curr){
如果(当前->左)
s、 按(当前->左);
否则如果(当前->右侧)
s、 推送(当前->右侧);
}否则如果(当前->左==上一个){
如果(当前->右侧)
s、 推送(当前->右侧);
}否则{
//这就是我们删除的地方
删除当前->数据;
删除curr;
s、 pop();
}
上一次=当前;
}
}

使用递归来删除在C++中编程时从C上构造的自下一次运行时停止的节点。在构造函数中进行分配,在Debug中进行DE分配。C++中使用递归来从下一次正常运行时间删除节点,使用C构造停止。分配在构造函数中完成,反分配在析构函数中完成;它是否可以像上面的评论那样实现?函数是否经过这一步直到达到NULL?当然,但是遍历步骤在哪里?在删除根目录之前,您需要访问左右两个子目录树。链接到站点外部的代码并不总是一个好主意。这个答案可能比一些任意的博客寿命更长,当链接文章被删除时,这个答案就变得无用了。把相关部分抄写到答案中。干杯!第一个对我有用。除了我没有删除p->数据;可以对“非指针”元素使用delete吗?如果(root==NULL){return;}删除root;它是否可以像上面的评论那样实现?函数是否经过这一步直到达到NULL?当然,但是遍历步骤在哪里?在删除根目录之前,您需要访问左右两个子目录树。链接到站点外部的代码并不总是一个好主意。这个答案可能比一些任意的博客寿命更长,当链接文章被删除时,这个答案就变得无用了。把相关部分抄写到答案中。干杯!第一个对我有用。除了我没有删除p->数据;你能用deleteo吗