1. 程式人生 > 其它 >【LeetCode】刪除二叉搜尋樹中的節點

【LeetCode】刪除二叉搜尋樹中的節點

刪除二叉搜尋樹中的節點

題目連結:https://leetcode-cn.com/problems/delete-node-in-a-bst/

題目大意:刪除指定key的節點,返回root

分析:樹是二叉搜尋樹,要求返回後仍然保持搜尋樹的位置

二叉搜尋樹:根節點值大於左孩子值,根節點值小於右孩子值

根據待刪除節點的情況,我們可以採取不同的措施

  • 如果目標節點大於當前節點值,則去右子樹中刪除;

  • 如果目標節點小於當前節點值,則去左子樹中刪除;

  • 如果目標節點就是當前節點,分為以下三種情況:

    • 其無左子:其右子頂替其位置,刪除了該節點;
    • 其無右子:其左子頂替其位置,刪除了該節點;
    • 其左右子節點都有:其左子樹轉移到其右子樹的最左節點的左子樹上,然後右子樹頂替其位置,由此刪除了該節點。

    第三種情況如圖:

  • 時間複雜度:O(H),H是樹的高度,尋找目標節點最壞情況需要O(H),刪除操作最壞情況也需要O(H);
  • 空間複雜度:O(H),遞迴棧的深度最壞情況為樹的高度;

func deleteNode(root *TreeNode, key int) *TreeNode {
	if root==nil{
		return nil
	}

	if key>root.Val{
		// 目標值大於當前值,則去當前節點的右子樹中刪除
		root.Right=deleteNode(root.Right,key)
	}else if key<root.Val{
		// 目標值小於當前值,則去當前節點的左子樹中刪除
		root.Left=deleteNode(root.Left,key)
	}else if key==root.Val{
		// 目標節點等於當前值,分析當前節點的左右孩子情況,採取不同策略

		if root.Left==nil{
			// 待刪除節點的左孩子為空,則右孩子頂替待刪除節點位置
			root=root.Right
		}else if root.Right==nil {
			// 待刪除節點的右孩子為空,則左孩子頂替待刪除節點位置
			root=root.Left
		}else if root.Right!=nil&&root.Left!=nil {
			// 待刪除節點的左右孩子都不為空,現在處理其左右孩子

			// 第一步:尋找待刪除root節點的右子樹的最左節點node
			node:=root.Right
			for node.Left!=nil{
				node=node.Left
			}

			// 第二步:root左子樹轉移到node的左子樹上,仍然儲存搜尋樹性質
			node.Left=root.Left

			// 第三步:root的右子樹頂替root位置
			root=root.Right

		}
	}
	return root
}