Python數據結構之搜索二叉樹(BST)

Python數據結構之搜索二叉樹(BST)

​ 二叉搜索樹也稱二叉排序樹或二叉查找樹。二叉搜索樹:一個二叉樹,可以爲空;如果不爲空,滿足一下性質(整體到部分遵循左小右大原則)。

  1. 非空左子樹的所有鍵值小於其根結點的鍵值。
  2. 非空右子樹的所有鍵值大於其根結點的鍵值。
  3. 左、右子樹都是二叉搜索樹。

BST插入

遵循左子樹的值小於右子樹的值原則進行插入操作

def insert(self, node, val):
    """插入元素(遞歸)"""

    if node is None:
        node = TreeNode(val)
        node.left = node.right = None
    else:
        #  遞歸左右結點實現,並返回值進行構建樹
        if val < node.val:
            node.left = self.insert(node.left, val)
        elif val > node.val:
            node.right = self.insert(node.right, val)

    return node

BST查找

BST查找指定元素

  • 遞歸方式
def find(self, node, val):
    """查找結點(遞歸)"""

    if node is None:
        return

    if val < node.val:
        return self.find(node.left, val)
    elif val > node.val:
        return self.find(node.right, val)
    return node
  • 迭代方式
def iter_find(node, val):
    """查找結點(迭代)"""

    while node:
        if val > node.val:
            node = node.right
        elif val < node.val:
            node = node.left
        else:  # node.val == val
            return node

    return None

BST查找最大值和最小值

  • 圖示

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-jZCBpDjS-1588990276673)(../Picture/BST.dio.png)]

  • 查找最大值(最大值應位於樹的最右面,其可能有左孩子或無孩子結點)
    def find_min(self, node):
        """找出最小的值(遞歸)"""

        if node is None:  # 空BST
            return

        elif node.left is None:
            return node
        else:
            return self.find_min(node.left)
  • 查找最小值(最小值應位於樹的最左面,其可能有右孩子或無孩子結點)
    def find_max(node):
        """找出最大值(迭代)"""

        if node:
            while node.right:  # 遍歷最右邊的結點
                node = node.right
                
        return node

BST刪除

二叉樹的刪除需要考慮以下三種情況

1)要刪除的是是葉結點:直接刪除,並修改其父結點指向爲空

2)要刪除的結點只有一個孩子結點:將其父結點指向刪除及結點的孩子結點。

3)要刪除的結點有左右兩棵子樹:用另一個結點替代被刪除的結點:右子樹的最小元素或者左子樹的最大元素

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Ef6y2y9l-1588990276678)(/home/gavin/Python/數據結構/Picture/BST刪除.dio.png)]

    def del_node(self, node, val):
        """刪除結點"""

        if node is None:
            print("刪除元素暫未找到")
		
        # 1.找刪除結點
        elif val < node.val:
            node.left = self.del_node(node.left, val)  # 與刪除後的新的結點進行連接
        elif val > node.val:
            node.right = self.del_node(node.right, val)
        else:
            # 2.刪除結點有左右子樹
            if node.left and node.right:
                tmp = self.find_min(node.right)  # 找尋右子樹的最小結點值
                node.val = tmp.val  # 把結點元素的置換
                node.right = self.del_node(node.right, node.val)
            else:
                
                tmp = node
                # 3.刪除結點有一個孩子結點或無孩子子結點
                if node.left is None:  # 有右孩子或無子結點
                    node = node.right
                elif node.right is None:  # 有左孩子或無子節點
                    node = node.left
                del tmp

        return node

BST測試

實例圖:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-SkCQqf7P-1588990276680)(../Picture/BST實例.dio.png)]

執行上述操作結果

BST先序遍歷: 7 3 1 2 5 10 9 12 
BST最小結點值: 1
BST最大結點值: 12
BST測試刪除操作
****************************************
BST刪除結點(右左右孩子)9 3 1 2 5 10 12 
BST刪除結點(有一個子孩子)9 3 2 5 10 12 
BST刪除結點(無子孩子)9 3 2 5 10 
****************************************
BST重新插入結點(7)9 3 2 5 7 10 

參考

數據結構與算法–二叉排序樹/二叉查找樹/二叉搜索樹 Python實現二叉排序樹/二叉查找樹/二叉搜索樹的遍歷、查找、刪除 Python最簡單的方式實現二叉排序樹

中國大學mooc數據結構

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章