面试题:写一个二分搜索树(Binary Search Tree),至少实现查找、删除和插入功能

二叉树具有天然递归结构
一个节点也是二叉树
NULL也是二叉树
二分搜索树是二叉树
每个节点的左子树也是二叉树
每个节点的右子树也是二叉树
二分搜索树的每个节点的值:
大于其左子树所有节点的值
小于其右子树所有节点的值

中序遍历的结果是顺序的

后序遍历的一个应用:
为二分搜索树释放内存

这里实现了二分搜索树的基本功能,包括插入、删除、查询等功能,后期会添加一些rank、select、floor、ceil等功能

from queue import Queue
from random import randint

class BSTree(object):
    class Node():
        def __init__(self,key,value):
            self.key = key    #关键字
            self.value = value
            self.left = None  #左孩子
            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 add(self,key,value):
        self.__root = self.__add(self.__root, key, value)
        
    def __add(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.__add(node.right, key, value)
        else:
            node.left = self.__add(node.left, key, value)
        return node

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

    def __contains(self,node,key):
        if node is None:
            return False

        if key==node.key:
            return True
        elif key > node.key:
            return self.__contains(node.right, key)
        elif key < node.key:
            return self.__contains(node.left, key)

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

    # 前序遍历以node为根节点的二分搜索树,递归算法
    def __preOrder(self, node):
        if node != None:
            print(node.key)
            self.__preOrder(node.left)
            self.__preOrder(node.right)

    # 二分搜索树的非递归前序遍历
    def preOrderNR(self):
        stack = []
        stack.append(self.__root)
        while len(stack) != 0:
            node = stack.pop()
            print(node.key)

            if node.right != None:
                stack.append(node.right)
            if node.left != None:
                stack.append(node.left)

    # 二分搜索树的中序遍历
    # 中序遍历的结果是顺序的
    def inOrder(self):
        self.__inOrder(self.__root)

    #中序遍历以node为根节点的二分搜索树,递归算法
    def __inOrder(self, node):
        if node != None:
            self.__inOrder(node.left)
            print(node.key)
            self.__inOrder(node.right)

    # 二分搜索树的后序遍历
    # 后序遍历的一个应用:为二分搜索树释放内存
    def postOrder(self):
        self.__postOrder(self.__root)

    # 后序遍历以node为根节点的二分搜索树,递归算法
    def __postOrder(self, node):
        if node != None:
            self.__postOrder(node.left)
            self.__postOrder(node.right)
            print(node.key)

    # 二分搜索树的层序遍历
    def levelOrder(self):
        q = Queue()
        q.put(self.__root)
        while not q.empty():
            node = q.get()
            print(node.key)

            if node.left != None:
                q.put(node.left)
            if node.right != None:
                q.put(node.right)

    # 寻找二分搜索树的最小元素
    def minimum(self):
        try:
            return self.__minimum(self.__root).key
        except Exception as e:
            print("BST is empty!")

    # 返回以node为根的二分搜索树的最小值所在的节点
    def __minimum(self, node):
        if node.left == None:
            return node
        return self.__minimum(node.left)

    # 寻找二分搜索树的最大元素
    def maximum(self):
        try:
            return self.__maximum(self.__root).key
        except Exception as e:
            print("BST is empty!")

    # 返回以node为根的二分搜索树的最大值所在的节点
    def __maximum(self, node):
        if node.right == None:
            return node
        return self.__maximum(node.right)

    # 从二分搜索树中删除最小值所在节点,返回最小值
    def removeMin(self):
        ret = self.minimum()
        self.__root = self.__removeMin(self.__root)
        return ret

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

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

    # 从二分搜索树中删除最大值所在节点,返回最大值
    def removeMax(self):
        ret = self.maximum()
        self.__root = self.__removeMax(self.__root)
        return ret

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

        node.right = self.__removeMax(node.right)
        return node

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

    # 删除以node为根的二分搜索树中值为e的节点, 递归算法
    # 返回删除节点后的新的二分搜索树的根
    def __remove(self, node, key):
        if node == None:
            return None

        if node.key > key:
            leftNode = self.__remove(node.left, key)
            return leftNode
        elif node.key < key:
            rightNode = self.__remove(node.right, key)
            return rightNode
        else: #node.key==key
            # 待删除的节点左子树为空
            if node.left == None:
                rightNode = node.right
                node.right = None
                self.__count -= 1
                return rightNode

            # 待删除的节点右子树为空
            if node.right == None:
                leftNode = node.left
                node.left = None
                self.__count -= 1
                return leftNode

            # 待删除的节点左右子树均不为空
            # 找到比待删除节点大的最小节点,即待删除节点右子树的最小节点
            # 用这个节点顶替待删除节点的位置
            successor = self.__minimum(node.right)
            successor.right = self.__removeMin(node.right)
            successor.left = node.left

            node.left = node.right = None
            return successor



if __name__ == '__main__':
    #arr = [randint(0,1000) for x in range(1,100)]
    arr = [28, 30, 16, 13, 29, 22, 42]
    #print(arr)
    bst = BSTree()
    for i in range(0, len(arr)):
        bst.add(arr[i], str(arr[i]))

    '''
    print(bst.contains(56))
    print(bst.size())
    print(bst.isEmpty())
    bst.preOrder()
    print("\n")
    bst.preOrderNR()
    bst.inOrder()
    print("\n")
    bst.postOrder()
    bst.levelOrder()
    '''

    bst.inOrder()
    print("\n")
    print("最小值为:",bst.minimum())
    print("删除:",bst.removeMin(),",删除后最小值为:",bst.minimum())


    print("最大值为:", bst.maximum())
    print("删除:", bst.removeMax(), ",删除后最大值为:", bst.maximum())

    bst.inOrder()

    e = int(input("你想删除:"))
    bst.remove(e)
    bst.inOrder()
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值