销毁树(析构函数)是否需要遍历通用树?

幽灵001

当销毁(当对象超出范围时)General Tree 是否有必要像使用双向链表那样遍历每个节点并删除它们?我正在编写的通用树是一个圆形,以便可以在恒定时间内完成插入。如果有人可以帮助我修复错误,那将会很有帮助。下面的析构函数当前导致堆栈溢出(我认为这是因为树是循环的)。

这是2个析构函数

~Node()
         {
        if(left){delete left;}
                if(next){delete next;}
                if(parent){delete parent;}
          }

对于一般树

 ~Gen()
       {
           if (head)
                 delete head; //call destructor on node
                 head = nullptr;
                 m_size = 0;
        }

这是节点类

class Node {
public:
    typedef Node* nodePtr;
    int data;
    //Left child- right sibling implementation
    nodePtr left, next, parent;
    int rank; //will be used for merging.
~Node()
         {
               if(left){delete left;}
                if(next){delete next;}
                if(parent){delete parent;}
          }
        
private:
    
    Node & operator =(const Node&);
};

这是使用上面节点的树

class Gen{
 public:
      typedef Node* nodePtr;
       Gen():m_size(0),head(0){}
       ~Gen()
       {
           if (head)
                 delete head; //call destructor on node
                 head = nullptr;
                 m_size = 0;
        }
        void push(int val)
        {
        nodePtr newNode = new Node;
        
        newNode->data = val;
        newNode->rank = 0;
        newNode->left = newNode->next = newNode->parent = 0; //set all pointers to null
        insertRoot(newNode); //call the inserthelper
        ++m_size;
        }
        //other functions (deleteMin, decreaseKey etc)
private:
int m_size;
nodePtr head;
nodePtr insertRoot(nodePtr newNode)
{
   //create a circular link
   if (!head)
    {
        head = newNode;
        newNode->next = newNode;
    }
    else
    {
        newNode->next = head->next;
        head->next = newNode;
        if (newNode->data < head->data)  //min heap (lazy insert)
            head = newNode;
    }
}
};

约丹夫塔诺斯基

您将需要以某种方式调用树中每个成员的析构函数,以递归方式(如您的实现)或迭代方法遍历树。

最简单的迭代方法是使用堆栈并在您沿树向下时添加元素,并在向上时弹出元素以删除它们。这篇文章中查看有关此方法的更多信息

因此,在您的特定情况下,通用树将有一个干扰器穿过树以破坏节点,而您不需要节点析构函数。析构函数看起来像:

#include <stack>
...
....
~Gen() {
    std::stack<Node*> s;
    s.push(head);
    Node* current;
    while (!s.empty()) {
        current = s.top();
        s.pop();
        if (current->left != nullptr) {
            s.push(current->left);
        };
        if (current->next != nullptr) {
            s.push(current->next);
        }
        delete current;
    }
    head = nullptr;
}

因此,当您沿着树向下前进时,您将子项添加到堆栈中并删除父项。一旦堆栈为空,树中的所有节点都将被删除。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

是否需要在C ++析构函数中明确销毁结构中固定大小的数组?

QDialogs中是否需要析构函数?

销毁删除仍然需要析构函数可访问吗?

Trie 树中 Trie 节点的析构函数

递归调用二叉树析构函数

二进制搜索树的析构函数

如何为Trie树编写析构函数

二叉树析构函数C ++

删除树项析构函数时未调用

二进制搜索树析构函数C ++

在销毁派生成员之前,在析构函数中调用通用函数

节点和二叉树构造函数和析构函数分段

返回的结构调用它自己的析构函数,该析构函数销毁分配的对象

使用 PPL 时是否需要将析构函数与异步函数同步?

全局变量构造函数/析构函数是否需要线程保护?

C ++多线程:构造函数和析构函数是否需要互斥体?

如果我还使用复制构造函数和重载=运算符,是否需要析构函数?

我是否需要在新类中声明构造函数和析构函数?

树的遍历是否随时可用?

树遍历中的高阶函数

TypeScript中是否有析构函数

是否有Java的析构函数?

当类同时包装STL容器和指针时,是否应该在类的析构函数中销毁STL容器?

遍历通用二叉树

std :: is_nothrow_move_constructible是否需要一个noexcept析构函数?

我是否需要显式调用基本虚拟析构函数?

同类型的placement-new是否还需要手动调用析构函数?

即使内存不是动态分配的,在析构函数中是否需要`delete ptr;`?

析构函数中的析构函数?