二进制搜索树的析构函数

Destructor for Binary Search Tree

本文关键字:析构函数 搜索树 二进制      更新时间:2023-10-16

我正在尝试为我的二进制搜索树编写析构函数,我知道如何在树中递归循环,但我不知道如何在析构函数中这样做,以便删除每个节点。

我的标题是:

struct Node;
typedef string TreeType;
typedef Node * TreePtr;
//Defines a Node
struct Node
{
    TreeType Info;
    int countDuplicates = 1;
    TreePtr Left, Right;
};
class Tree
{
public:
    //Constructor
    Tree();
    //Destructor
    ~Tree();
    //Retruns true if the tree is Empty
    bool Empty();
    //Inserts a Node into the tree
    bool Insert(TreeType);
    //Delete decides what type of delection needs to occur, then calls the correct Delete function
    bool Delete(Node * , Node * );
    //Deletes a leaf node from the tree
    bool DeleteLeaf(TreePtr, TreePtr);
    //Deletes a two child node from the tree
    bool DeleteTwoChild(TreePtr);
    //Deletes a one child node from the tree
    bool DeleteOneChild(TreePtr, TreePtr);
    //Finds a certain node in the tree
    bool Find(TreeType);
    //Calculates the height of the tree
    int Height(TreePtr);
    //Keeps a count of the nodes currently in the tree;
    void Counter();
private:
    //Prints the nodes to the output text file in order alphabetically
    void InOrder(ofstream &,TreePtr);
    //Defines a TreePtr called Root
    TreePtr Root;
    //Defines a TreePtr called Current
    TreePtr Current;
    //Defines a TreePtr called Parent
    TreePtr Parent;
};

我的构造函数是:

Tree::Tree()
{
    Root = NULL;
    Current = NULL;
    Parent = NULL;
}

有没有一种方法可以递归地调用析构函数?如果没有,我如何遍历每个节点来删除它。

void Tree::DestroyRecursive(TreePtr node)
{
    if (node)
    {
        DestroyRecursive(node->left);
        DestroyRecursive(node->right);
        delete node;
    }
}
Tree::~Tree()
{
    DestroyRecursive(Root);
}

您需要两个析构函数:

Tree::~Tree()
{
    delete Root;
}

Node::~Node()
{
    delete Left;
    delete Right;
}

但你在这里并不需要两节课。每个Node都是一棵树。

当您调用delete或您的Tree到生命周期结束时(从块中退出,如末尾的示例),您必须delete TreeNode s,delete运算符将调用析构函数,请参阅末尾的示例。

当调用Tree析构函数时,这将使Tree从内存中完全消失。

试试这个:

#include <iostream>
using namespace std;
class Node {
    Node *left, *right;
public:
    Node(Node *l, Node *r);
    ~Node();
};
class Tree {
    Node *root;
public:
    Tree(Node *rt);
    ~Tree();
};
Tree::Tree(Node *rt):root(rt) {
    cout << "new Tree with root node at " << rt << endl;
}
Tree::~Tree() {
    cout << "Destructor of Tree" << endl;
    if (root) delete root;
}
Node::Node(Node *l, Node *r):left(l), right(r) {
    cout << "Node@"
        << this
        << "(left:" << l
        << ", right:" << r << ")"
        << endl;
}   
Node::~Node() {
    cout << "~Node@" << this 
        << endl;
    if (left) delete left;
    if (right) delete right;
}
int main() {
    Tree t(
        new Node(
            new Node(
                new Node(
                    new Node(0, 0), 
                    0),
                0),
            new Node(0, new Node(0, 0))));
}

这是我的实现。树等于树节点。

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
    ~TreeNode() {
        delete left;
        delete right;
    }
    ...
};

只需删除树的根节点,整个树就会被递归删除。

TreeNode* root = new TreeNode(2);
delete root;

您可能已经知道删除的操作。

当delete用于释放C++类对象的内存时对象的析构函数在对象的内存被调用之前被调用解除分配(如果对象具有析构函数)。

因此,在treeNode的析构函数中,您只需要销毁手动分配的左指针和右指针。您不需要担心节点本身的释放。

最好的方法是使用智能指针,当ref计数为0:时,它会递归地为您删除

class TreeNode {
    private:
        TreeType info_;
        unique_ptr<TreeNode> left_, right_;
    public:
        TreeNode(): info_(""), left_(nullptr), right_(nullptr) {}
        TreeNode(TreeType info): info_(info), left_(nullptr), right_(nullptr) {}
};

使用现代C++,您应该永远不需要创建自己的析构函数(除非您正在创建自己的RAII代理类-罕见),也不需要调用new/delete。