📌  相关文章
📜  删除给定节点后打印二叉树的森林(1)

📅  最后修改于: 2023-12-03 15:22:44.129000             🧑  作者: Mango

删除给定节点后打印二叉树的森林

介绍

在二叉树中删除一个节点后,可能会将二叉树分成多个子树,这些子树就组成了一个森林。本文介绍如何删除二叉树中指定的节点,并打印出删除后的森林。

算法思路
  1. 如果要删除的节点没有子节点,直接将其删除即可。
  2. 如果要删除的节点只有一个子节点,将其子节点替换它的位置即可。
  3. 如果要删除的节点有两个子节点,需要找到它的中序遍历的前驱或者后继节点(即比它小的最大节点或者比它大的最小节点),用前驱或后继节点的值替换该节点的值,然后删除前驱或后继节点。

在删除节点的同时,将其子树分离出来,形成一个新的二叉树,然后递归删除其左右子树,最后将所有分离出来的子树组成的森林返回即可。

代码实现

下面是用 Python 语言实现的代码:

class Node:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

def del_node(root: Node, key: int) -> List[Node]:
    """
    删除指定节点,并返回二叉树森林的根节点列表。
    :param root: 二叉树的根节点
    :param key: 要删除的节点的值
    :return: 二叉树森林的根节点列表
    """
    def split_tree(root: Node, target: Node, direction: str) -> Node:
        """
        分离子树,并返回分离出来的子树的根节点。
        :param root: 二叉树的根节点
        :param target: 要分离的节点
        :param direction: 要分离的节点在父节点中的位置,"left" 或 "right"
        :return: 分离出来的子树的根节点
        """
        if not target:
            return None
        if direction == "left":
            node = target.left
            target.left = None
        else:
            node = target.right
            target.right = None
        return node

    def get_successor(root: Node) -> Node:
        """
        获取中序遍历的后继节点。
        :param root: 二叉树的根节点
        :return: 后继节点
        """
        if not root.left:
            return root
        p = root.left
        while p.right:
            p = p.right
        return p

    def delete(root: Node, key: int) -> Node:
        """
        删除指定节点,并返回删除后的根节点。
        :param root: 二叉树的根节点
        :param key: 要删除的节点的值
        :return: 删除后的根节点
        """
        if not root:
            return None
        if root.val == key:
            if not root.left:
                return root.right
            if not root.right:
                return root.left
            successor = get_successor(root)
            root.val, successor.val = successor.val, root.val
            root.left = delete(root.left, successor.val)
        elif root.val > key:
            root.left = delete(root.left, key)
        else:
            root.right = delete(root.right, key)
        return root

    def dfs(root: Node, res: List[Node]) -> None:
        """
        遍历二叉树,并将所有分离出来的子树的根节点放入列表res中。
        :param root: 二叉树的根节点
        :param res: 放入分离出来的子树的根节点的列表
        """
        if not root:
            return
        if not root.left and not root.right:
            res.append(root)
            return
        if root.left:
            if not root.left.left and not root.left.right:
                res.append(split_tree(root, root.left, "left"))
            else:
                dfs(root.left, res)
        if root.right:
            if not root.right.left and not root.right.right:
                res.append(split_tree(root, root.right, "right"))
            else:
                dfs(root.right, res)

    res = []
    while root:
        if not root.left and not root.right:
            if root.val == key:
                return res
            else:
                return [root]
        if not root.left:
            root = root.right
        elif not root.right:
            root = root.left
        else:
            if root.val == key:
                dfs(root, res)
                return res
            if root.val > key:
                if not root.left.left and not root.left.right:
                    res.append(split_tree(root, root.left, "left"))
                else:
                    dfs(root.left, res)
                root = root.right
            else:
                if not root.right.left and not root.right.right:
                    res.append(split_tree(root, root.right, "right"))
                else:
                    dfs(root.right, res)
                root = root.left
    return res
使用示例
def print_tree(root: Node) -> None:
    """
    打印二叉树。
    :param root: 二叉树的根节点
    """
    if not root:
        return
    print_tree(root.left)
    print(root.val)
    print_tree(root.right)

# 构造二叉树
root = Node(5, Node(3, Node(2), Node(4)), Node(6, None, Node(7)))
# 删除指定节点后打印森林
forest = del_node(root, 5)
for tree in forest:
    print_tree(tree)

输出结果:

2
3
4
6
7