📜  使用层序遍历删除二叉树中的给定节点 K(1)

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

使用层序遍历删除二叉树中的给定节点 K

在二叉树中删除某个节点通常有两种方法:

  1. 递归方式,对于每一个节点,判断是否为要删除的节点,如果是则删除,否则对该节点的左右子节点进行递归操作。
  2. 迭代方式,使用栈或队列对于每一个节点进行遍历,判断是否为要删除的节点,如果是则删除,否则将该节点的左右子节点加入栈或队列中。

本文介绍的是使用迭代方式,也就是使用层序遍历进行删除。

算法步骤
  1. 将根节点加入队列中。
  2. 对于每一个节点,判断是否为要删除的节点,如果是,则将该节点标记为待删除节点。
  3. 如果该节点的左右子节点不为空,则将左右子节点加入队列中。
  4. 循环遍历队列,直到队列为空。
  5. 遍历所有的待删除节点,将其父节点的指针指向其兄弟节点。
算法实现

实现代码如下:

def deleteNode(root, key):
    if not root:  # 树为空
        return None

    queue = [root]
    to_delete = []  # 待删除节点列表
    while queue:
        node = queue.pop(0)
        if node and node.val == key:
            to_delete.append(node)
        if node and node.left:
            queue.append(node.left)
        if node and node.right:
            queue.append(node.right)

    # 遍历所有待删除节点,将其父节点的指针指向其兄弟节点
    for i in range(len(to_delete)):
        node = to_delete[i]
        if node == root:  # 待删除节点为根节点
            if node.left:
                root = node.left
                if node.right:
                    root.right = node.right
            elif node.right:
                root = node.right
            else:
                root = None
        else:
            parent = findParent(root, node.val)
            if not parent:  # 待删除节点没有父节点,说明该节点不在树中
                continue
            if parent.left == node:
                if node.left:
                    parent.left = node.left
                    if node.right:
                        node.left.right = node.right
                elif node.right:
                    parent.left = node.right
                else:
                    parent.left = None
            else:
                if node.left:
                    parent.right = node.left
                    if node.right:
                        node.left.right = node.right
                elif node.right:
                    parent.right = node.right
                else:
                    parent.right = None

    return root


def findParent(root, key):
    if not root:  # 树为空
        return None
    if root.val == key:  # 根节点即为待查找节点
        return None

    queue = [root]
    while queue:
        node = queue.pop(0)
        if node and node.left:
            if node.left.val == key:
                return node
            queue.append(node.left)
        if node and node.right:
            if node.right.val == key:
                return node
            queue.append(node.right)

    return None
算法分析

时间复杂度:O(n^2),因为在删除节点的时候需要查找父节点,而在最坏的情况下,父节点可能在二叉树的最底层,因此需要遍历整个二叉树,此时时间复杂度为 n^2。

空间复杂度:O(n),因为使用了队列来存储节点,最多需要存储 n 个节点。

总结

本文介绍了如何使用层序遍历来删除二叉树中的给定节点 K,算法实现比较容易理解,但是时间复杂度比较高。如果对时间复杂度有要求的话,建议使用递归的方式来实现。