Python实现二分查找树

前言

本文用Python语言实现二分查找,以及二分搜索树,以及二叉树的前序中序后序遍历,并增加辅助测试函数验证,具体完整代码可以去我的 GitHub 网站下载。

程序

1. 二分查找

# 二分查找 有序数组arr 查找target
def binarySearch(arr, n, target):
    # 在arr[l...r]中查找target
    l = 0
    r = n - 1
    while (l <= r):
        # mid = (l+r) // 2 # 此处可能产生整型溢出
        mid = l + (r - l) // 2
        if (arr[mid] == target):
            return mid
        if (target < arr[mid]):
            r = mid - 1
        else:
            l = mid + 1
    # 没找到 返回-1
    return -1

2. 二分搜索树

# 二分搜索树
class BST:
    # 树中的节点为私有的类 外界不需要了解二分搜索树的具体实现
    class Node:
        def __init__(self, key, value):
            self.key = key
            self.value = value
            self.left = self.right = None

    def __init__(self):
        self.__root = None
        self.__count = 0

    def size(self):
        return self.__count

    def isEmpty(self):
        return self.__count == 0

    # 插入一个新的节点 采用递归结构, 返回插入新节点后的二叉搜索树的根
    def insert(self, key, value):
        self.__root = self.__insert(self.__root, key, value)

    # 以node为根的二分搜索树中是否包含键值为key的节点 使用递归算法
    def contain(self, key):
        return self.__contain(self.__root, key)

    # 以node为根结点的二分搜索树中查找key对应的value, 若value不存在 返回null
    def search(self, key):
        return self.__search(self.__root, key)

    # 二叉树的前序遍历
    def preOrder(self):
        self.__preOrder(self.__root)

    # 二叉树的中序遍历
    def inOrder(self):
        self.__inOrder(self.__root)

    # 二叉树的后序遍历
    def postOrder(self):
        self.__postOrder(self.__root)

    # 二分搜索树的层序遍历 利用队列的数据结构
    def levelOrder(self):
        # 初始化一个队列
        q = Queue()
        q.put(self.__root)
        while not q.empty():
            node = q.get()
            print(node.key)
            if node.left is not None:
                q.put(node.left)
            if node.right is not None:
                q.put(node.right)

    # 寻找二分搜索树的最小键值
    def minimum(self):
        if self.__count <= 0:
            print('二分搜索树里面没有元素了!!!')
            raise IndexError
        minNode = self.__minimum(self.__root)
        return minNode.key

    # 寻找树中的最大键值
    def maxmum(self):
        if self.__count <= 0:
            print('二分搜索树里面没有元素了!!!')
            raise IndexError
        maxNode = self.__maxmum(self.__root)
        return maxNode.key

    # 从二分搜索属树种删除最小值所在节点
    def removeMin(self):
        if self.__root is not None:
            self.__root = self.__removeMin(self.__root)

    def removeMax(self):
        if self.__root is not None:
            self.__root = self.__removeMax(self.__root)

    # 从二分搜索树种删除键值为key的节点
    def remove(self, key):
        self.__root = self.__remove(self.__root, key)

3. 二分搜索树辅助函数

   # 删除以node为根的二分搜索树种键值为key的节点,递归算法
    # 返回删除后的节点后新的二分搜索树
    def __remove(self, node, key):
        if node is None:
            return None
        # 递归寻找
        if key > node.key:
            node.right = self.__remove(node.right, key)
            return node
        elif key < node.key:
            node.left = self.__remove(node.left, key)
            return node
        else:  # key==node.key的情况
            # 待删除的节点左子树为空
            if node.left is None:
                rightNode = node.right
                node.right = None
                self.__count -= 1
                return rightNode
            # 待删除的节点右子树为空
            if node.right is None:
                leftNode = node.left
                node.left = None
                self.__count -= 1
                return leftNode

            # 待删除的节点左右节点都不为空的情况
            # 找到比待删除节点大的最小节点 即待删除节点右子树的最小节点
            # 用这个节点顶替待删除节点的位置
            successor = self.Node(node.key, node.value)
            self.__count += 1
            successor.right = self.__removeMin(node.right)
            successor.left = node.left

            node.left = node.right = None
            self.__count -= 1

            return successor

    # 删除掉以node为根的二分搜索书中的最小节点
    # 返回删除节点后的二分搜索树的根节点
    def __removeMin(self, node):
        if node.left is not None:
            rightNode = node.right
            print(node.key)
            print('已经删除')
            node.right = None
            self.__count -= 1
            return rightNode

        node.left = self.__removeMin(node.left)
        return node

    # 删除掉以node为根的二分搜索书中的最大节点
    # 返回删除节点后的二分搜索树的根节点
    def __removeMax(self, node):
        if node.right is not None:
            leftNode = node.left
            print(node.key)
            print('已经删除')
            node.left = None
            self.__count -= 1
            return leftNode
        node.right = self.__removeMax(node.right)
        return node

    def __minimum(self, node):
        if (node.left is None):
            return node
        return self.__minimum(node.left)

    def __maxmum(self, node):
        if node.right is None:
            return node
        return self.__maxmum(node.right)

    def __insert(self, node, key, value):
        if (node is None):
            self.__count += 1
            return self.Node(key, value)

        if (key == node.key):
            node.value = value
        elif (key > node.key):
            node.right = self.__insert(node.right, key, value)
        else:
            node.left = self.__insert(node.left, key, value)
        return node

    def __contain(self, node, key):

        if node is None:
            return False
        if (key == node.key):
            return True
        elif (key > node.key):
            return self.__contain(node.right, key)
        else:
            return self.__contain(node.left, key)

    def __search(self, node, key):
        if node is None:
            return None
        if key == node.key:
            return node.value
        elif key > node.key:
            return self.__search(node.right, key)
        else:
            return self.__search(node.left, key)

    def __preOrder(self, node):
        if node is not None:
            print(node.key)
            self.__preOrder(node.left)
            self.__preOrder(node.right)

    def __inOrder(self, node):
        if node is not None:
            self.__inOrder(node.left)
            print(node.key)
            self.__inOrder(node.right)

    def __postOrder(self, node):
        if node is not None:
            self.__postOrder(node.left)
            self.__postOrder(node.right)
            print(node.key)

4. main函数

if __name__ == '__main__':
    n = 100
    start = 0
    end = 100
    # arr = genNearlyOrderArray(n, swapTimes=50000)
    # arr = genRandomArray(n, start, end)
    arr=np.random.randint(end, size=n)
    arr2 = arr.copy()
    arr3 = arr.copy()
    arr4 = arr.copy()
    arr5 = arr.copy()
    print(arr)
    bst = BST()
    # 测试的搜索二叉树的键类型为int 值类型为string
    for i in range(n):
        bst.insert(arr[i], str(arr[i]))
    maxN = bst.maxmum()
    print(maxN)
    bst.remove(99999)
    print(bst.maxmum())

结果

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值