1. 程式人生 > >leetcode.450.刪除二叉樹中的節點

leetcode.450.刪除二叉樹中的節點

450.刪除二叉樹中的節點

給定一個二叉搜尋樹的根節點 root 和一個值 key,刪除二叉搜尋樹中的 key 對應的節點,並保證二叉搜尋樹的性質不變。返回二叉搜尋樹(有可能被更新)的根節點的引用。

一般來說,刪除節點可分為兩個步驟:

首先找到需要刪除的節點;
如果找到了,刪除它。
說明: 要求演算法時間複雜度為 O(h),h 為樹的高度。

示例:

root = [5,3,6,2,4,null,7]
key = 3

    5
   / \
  3   6
 / \   \
2   4   7

給定需要刪除的節點值是 3,所以我們首先找到 3 這個節點,然後刪除它。

一個正確的答案是 [5,4,6,2,null,null,7], 如下圖所示。

    5
   / \
  4   6
 /     \
2       7

另一個正確答案是 [5,2,6,null,4,null,7]。

    5
   / \
  2   6
   \   \
    4   7

中序立即先行者:在該節點的左子樹往右尋找,直到該節點的右子針為None,這個節點就是中序立即先行者。
中序立即後繼者:該節點的右子樹往左尋找,直到左子針的為None.
虛擬碼

MinNode(x)
	'''
	返回後繼者
	'''
	if x.left == NIL
		return x
	return MinNode(x.left)
DeleteMin(ptr)
'''
主程式
'''
	'''
	返回刪除了後繼者的右子樹
	'''
	if ptr.left == NIL
		return ptr.right
	ptr.left = DeleteMin(ptr.left)
	return ptr
DeleteNode(root,key)
	if root == NIL#如果樹根為NIL,就返回NIL
		return NIL
	if root.val > key#如果key在左子樹中,就修改root的左子樹
		root.left = DeleteNode(root.left,key)
		return root
	else lif root.val < key#如果key在右子樹中,就修改root的右子樹
		root.right = DeleteNode(root.right,key)
		return root
	else:
	#如果key就是在root
	##如果key只有左子樹,就返回它的左子樹
		 if root.right == NIL
			return root.left
	##反之如果key只有右子樹,就返回它的右子樹
		else lif root.left == NIL
			return root.right
	## 如果root,有兩個子樹,可以返回root的先行者或者後繼者,這裡以後繼者為例
		else:
			succnode = MinNode(root.right)#succnode是後繼者
			succnode.right = DeleteMin(root.right)#返回刪除了後繼者的右子樹
			succnode.left = root.left #後繼者的左子樹就是樹根的左子樹
			return succnode #返回後繼者	

python實現


class Solution(object):
    def deleteNode(self, root, key):
        """
        :type root: TreeNode
        :type key: int
        :rtype: TreeNode
        """
        def minnode(x):
            '''
            返回最小關鍵字
            '''
            if x.left == None:
                return
x return minnode(x.left) def deleteMin(ptr): ''' 反回刪除了最小關鍵字的二叉樹 ''' if ptr.left == None: return ptr.right ptr.left = deleteMin(ptr.left) return ptr if root == None: return None if root.val > key: #如果key在左子樹中 root.left = self.deleteNode(root.left,key) return root elif root.val < key: #如果key在右子樹中 root.right = self.deleteNode(root.right,key) return root else: #如果key在root上 ## 如果root只有左子樹 if root.right == None: return root.left ## 如果root只有右子樹 elif root.left == None: return root.right ## root有兩個子樹,返回root的後繼 else: succnode = minnode(root.right) succnode.right = deleteMin(root.right) succnode.left = root.left return succnode