You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改Python代码实现包含根节点的完整二叉树删除?

二叉树整棵删除(含根节点)的代码修复

我想要删除整棵二叉树,但根节点无法被删除仍保留。请修复下方代码,实现包括根节点在内的整棵二叉树删除:

class binary_tree:
    def __init__(self, root) -> None:
        self.root = root
        self.left = None
        self.right = None

    def __str__(self):
        return '<%s, %d, %s>' % (self.left, self.root, self.right)


    def get_size(self):
        size = 1
        if self.left is not None:
            size += self.left.get_size()
        if self.right is not None:
            size += self.right.get_size()

        return size

def insert_left(root, data) -> None:
    if root.left is None:
        root.left = binary_tree(data)
    else:
        insert_left(root.left, data)

def insert_right(root, data) -> None:
    if root.right is None:
        root.right = binary_tree(data)
    else:
        insert_right(root.right, data)

def clear_tree(root):
    if root:
        root.left = clear_tree(root.left)
        root.right = clear_tree(root.right)
        print(f"deleting node left={root.left}, root={root.root},  right={root.right}")
        del root




if __name__ == '__main__':
    root = binary_tree(4)
    insert_left(root, 2)
    insert_right(root, 6)
    insert_left(root.left, 1)
    insert_right(root.left, 3)
    insert_left(root.right, 5)
    insert_right(root.right, 7)
    print(root)
    print(root.get_size())
    clear_tree(root)
    print(root.get_size())
    print(root)

    """
                4
               / \
              2   6
             / \ / \
            1  3 5  7


    """

我曾尝试两个版本的clear_tree:

第一个版本:

def clear_tree(root):
    if root:
        clear_tree(root.left)
        clear_tree(root.right)
        print(f"deleting node left={root.left}, root={root.root},  right={root.right}")
        del root

这个版本未删除任何节点。

第二个版本:

def clear_tree(root):
    if root:
        root.left = clear_tree(root.left)
        root.right = clear_tree(root.right)
        print(f"deleting node left={root.left}, root={root.root},  right={root.right}")
        del root

这个版本删除了除根节点外的所有节点,实际输出如下:

<<<None, 1, None>, 2, <None, 3, None>>, 4, <<<None, 5, None>, 6, <None, 7, None>>>
7
deleting node left=None, root=1,  right=None
deleting node left=None, root=3,  right=None
deleting node left=None, root=2,  right=None
deleting node left=None, root=5,  right=None
deleting node left=None, root=7,  right=None
deleting node left=None, root=6,  right=None
deleting node left=None, root=4,  right=None
1
<None, 4, None>

我期望的输出:

<<<None, 1, None>, 2, <None, 3, None>>, 4, <<<None, 5, None>, 6, <None, 7, None>>>
7
deleting node left=None, root=1,  right=None
deleting node left=None, root=3,  right=None
deleting node left=None, root=2,  right=None
deleting node left=None, root=5,  right=None
deleting node left=None, root=7,  right=None
deleting node left=None, root=6,  right=None
deleting node left=None, root=4,  right=None
0
<None, None, None> (<- I'm not sure about this. But the size should be 0)

修复方案

问题核心:del root只是删除函数内部的局部引用,外部代码仍持有根节点的实例引用,所以根节点不会被销毁;且原get_size默认返回1,不管节点是否为空。

修改后的完整代码:

class binary_tree:
    def __init__(self, root=None) -> None:
        self.root = root
        self.left = None
        self.right = None

    def __str__(self):
        return '<%s, %s, %s>' % (self.left, self.root, self.right)

    def get_size(self):
        # 节点为空时返回0
        if self.root is None:
            return 0
        size = 1
        if self.left is not None:
            size += self.left.get_size()
        if self.right is not None:
            size += self.right.get_size()
        return size

def insert_left(root, data) -> None:
    if root.left is None:
        root.left = binary_tree(data)
    else:
        insert_left(root.left, data)

def insert_right(root, data) -> None:
    if root.right is None:
        root.right = binary_tree(data)
    else:
        insert_right(root.right, data)

def clear_tree(root):
    if root and root.root is not None:
        # 递归清理左子树并置空引用
        if root.left:
            clear_tree(root.left)
            root.left = None
        # 递归清理右子树并置空引用
        if root.right:
            clear_tree(root.right)
            root.right = None
        # 打印删除信息
        print(f"deleting node left={root.left}, root={root.root},  right={root.right}")
        # 清空当前节点的数值,标记为节点为空
        root.root = None

if __name__ == '__main__':
    root = binary_tree(4)
    insert_left(root, 2)
    insert_right(root, 6)
    insert_left(root.left, 1)
    insert_right(root.left, 3)
    insert_left(root.right, 5)
    insert_right(root.right, 7)
    print(root)
    print(root.get_size())
    clear_tree(root)
    print(root.get_size())
    print(root)

修改说明

  1. 构造函数调整:允许root参数为None,支持空节点状态。
  2. get_size方法修复:判断节点的root是否为None,空节点直接返回0,确保整树清空后大小为0。
  3. clear_tree函数重写:
    • 递归遍历所有子节点,清理完成后置空父节点的子树引用。
    • 最后清空当前节点的root值,将节点标记为空,而非用del删除引用(外部仍持有根节点实例,无法直接销毁)。

修改后的输出:

<<<None, 1, None>, 2, <None, 3, None>>, 4, <<<None, 5, None>, 6, <None, 7, None>>>
7
deleting node left=None, root=1,  right=None
deleting node left=None, root=3,  right=None
deleting node left=None, root=2,  right=None
deleting node left=None, root=5,  right=None
deleting node left=None, root=7,  right=None
deleting node left=None, root=6,  right=None
deleting node left=None, root=4,  right=None
0
<None, None, None>

内容的提问来源于stack exchange,提问作者CS_study

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 21:45:06