C++ 二叉树析构函数的递归调用

C++ 二叉树析构函数的递归调用,c++,data-structures,binary-search-tree,destructor,C++,Data Structures,Binary Search Tree,Destructor,据我所知,二进制搜索树析构函数的代码如下: ~tree(){ remove(root); } void remove(node* root) { if (root == NULL) return; remove(root->left); remove(root->right); delete root; } 但是,我想知道下面对析构函数的调用是否有效 ~node(){ delete left; delete right;

据我所知,二进制搜索树析构函数的代码如下:

~tree(){

    remove(root);
}

void remove(node* root) 
{
    if (root == NULL) return;
    remove(root->left);
    remove(root->right);
    delete root;
}
但是,我想知道下面对析构函数的调用是否有效

~node(){
    delete left;
    delete right;
}

~tree(){
    delete root;
}
我的理解是,删除根节点会自动调用子节点并删除它们。这是正确的假设吗如果确实正确,验证析构函数是否工作的简单方法是什么?

{{这部分文章后来添加了}

我在这里使用第二种方法。通过输出表达式验证,下面的代码似乎不起作用,因为我得到了一个delete输出(似乎是针对根节点的)


理想情况下,应该有3个这样的表达式,但我得到的只有1个。

是的,如果叶节点的左和右都等于nullptr,它将起作用

符合C++标准(5.3.5删除)< /P> 6如果删除表达式的操作数值不是空值 指针值,删除表达式将调用析构函数 (如果有)用于要删除的对象或数组元素。在里面 对于数组,元素将按顺序销毁 递减地址(即,与完成 其构造;见12.6.2)

因此,只有当节点不是空指针值时,才会调用节点的析构函数

如果您想检查析构函数是否确实在工作,那么只需在析构函数体中插入一条输出语句

这是一个演示程序

#include <iostream>

struct node
{
    node *next;
    int x;
    ~node()
    {
        std::cout << "inside node: " << x << std::endl;
        delete next;
    }
};

void push_front( node **tree, int x )
{
    node *n = new node;
    n->x = x;
    n->next = *tree;

    *tree = n;
}

void clear( node **tree )
{
    delete *tree;
    *tree = nullptr;
}

int main()
{
    node *tree = nullptr;

    for ( int i = 0; i < 10; i++ ) push_front( &tree, i );

    clear( &tree );
}

不,这不起作用,因为析构函数将允许对
NULL
指针调用
delete

您应该小心在树中创建循环。如果您有一个指向自身的树,则此代码(两个版本)可能会爆炸。如果您使用智能指针而不是常规指针,则您的析构函数将变为空,并且您不需要删除。请详细说明智能指针好吗?有没有一种简单的方法来测试析构函数是否工作?@n.m,有没有一种方法可以验证析构函数是否工作?我的理解是,如果我在析构函数中包含“cout”语句,它将对树中的每个元素重复,这将在某种程度上验证析构函数是否工作。这是正确的吗?这个
{margin}
太小了,但基本上您使用的是
std:unique\u ptr left,right而不是
节点*左,*右
然后忘记
delete
。情况应该总是这样,否则它们不是叶节点。@Codor Yes这是停止递归的条件。谢谢你的回答。你能帮我确认一下析构函数是否正常工作吗?我的理解是,如果我在析构函数中包含“cout”语句,它将对树中的每个元素重复,这将在某种程度上验证析构函数是否工作。对吗?顺便说一下,我已经试过了。头部节点仅显示一个输出表达式。这是事情不对的迹象吗?请检查我在原始帖子中所做的编辑。谢谢
 Deleting:
#include <iostream>

struct node
{
    node *next;
    int x;
    ~node()
    {
        std::cout << "inside node: " << x << std::endl;
        delete next;
    }
};

void push_front( node **tree, int x )
{
    node *n = new node;
    n->x = x;
    n->next = *tree;

    *tree = n;
}

void clear( node **tree )
{
    delete *tree;
    *tree = nullptr;
}

int main()
{
    node *tree = nullptr;

    for ( int i = 0; i < 10; i++ ) push_front( &tree, i );

    clear( &tree );
}
Compiled with /EHsc /nologo /W4
main.cpp

Compilation successful!

Total compilation time: 187ms

inside node: 9

inside node: 8

inside node: 7

inside node: 6

inside node: 5

inside node: 4

inside node: 3

inside node: 2

inside node: 1

inside node: 0

Total execution time: 734ms