【LeetCode】刪除二叉搜尋樹中的節點
阿新 • • 發佈:2022-04-07
刪除二叉搜尋樹中的節點
題目連結: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 }