python二叉排序树

参考:www.bilibili.com/video/BV1E4…

python实现

class Node:
    def __init__(self, value, left=None, right=None):
        self.value = value
        self.left = left
        self.right = right

    def __str__(self):
        return f"node [value={self.value}]"

    def preOrder(self, node):
        if node is None:
            return
        else:
            print(node)
            if node.left:
                node.left.preOrder(node.left)
            if node.right:
                node.right.preOrder(node.right)

    def addNode(self, node):
        if node is None or not isinstance(node, Node):
            return
        if self.value > node.value:
            if self.left is None:
                self.left = node
            else:
                self.left.addNode(node)
        else:
            if self.right is None:
                self.right = node
            else:
                self.right.addNode(node)

    def searchNode(self, value):
        if self.value == value:
            return self
        else:
            if self.left:
                node = self.left.searchNode(value)
                if node:
                    return node
            if self.right:
                node = self.right.searchNode(value)
                if node:
                    return node

    def getParentNode(self, value):
        if (self.left and self.left.value == value) or (self.right and self.right.value == value):
            return self
        # 向左递归
        if self.value > value:
            node = self.left.getParentNode(value)
            if node:
                return node
        # 向右递归
        elif self.value < value:
            node = self.right.getParentNode(value)
            if node:
                return node
        else:
            return None


class BinarySortTree:
    def __init__(self, root=None):
        self.root = root

    # 添加节点
    def addNode(self, node):
        if node is None or not isinstance(node, Node):
            return
        # 没有根节点的情况
        if self.hasRootNode():
            self.root = node
        # 有根节点的情况
        else:
            self.root.addNode(node)

    # 查找
    def searchNode(self, value):
        if not self.hasRootNode():
            return self.root.searchNode(value)
        else:
            print("当前树为空")

    # 前序遍历
    def preOrder(self):
        if not self.hasRootNode():
            self.root.preOrder(self.root)

    # 判断root是否为空
    def hasRootNode(self):
        return self.root is None

    def getMinValue(self, node):
        if node:
            while node.left:
                node = node.left
            self.delNode(node.value)
            return node.value
        else:
            print("node为空节点")

    # 3种情况
    # 1.删除的是叶子节点,也就是左右节点都为空
    # 2.删除的是有一个叶子节点的子节点
    # 3.删除的是有2个叶子节点的子节点
    def delNode(self, value):
        if self.hasRootNode():
            print("树为空")
        else:
            targetNode = self.searchNode(value)
            # 没找到目标节点
            if not targetNode:
                print("没有找到该节点")
                return
            # 如果没有找到早就return了,不会进去下面的步骤
            if not self.root.left and not self.root.right:
                self.root = None
                return
            parentNode = self.getParent(value)
            # 叶子节点
            if not targetNode.left and not targetNode.right:
                if parentNode.left and parentNode.left.value == targetNode.value:
                    parentNode.left = None
                elif parentNode.right and parentNode.right.value == targetNode.value:
                    parentNode.right = None
            # 有左右子节点
            elif targetNode.left and targetNode.right:
                targetNode.value = self.getMinValue(targetNode.right)
            # 有左或右一个子节点
            else:
                # 目标节点的左子节点不为空
                if targetNode.left:
                    # 父节点是否为空
                    if parentNode:
                        # 目标节点是父节点的左节点
                        if parentNode.left and parentNode.left.value == value:
                            parentNode.left = targetNode.left
                        else:
                            parentNode.right = targetNode.left
                    else:
                        self.root = targetNode.left
                # 目标节点的右子节点不为空
                else:
                    # 父节点是否为空
                    if parentNode:
                        if parentNode.left and parentNode.left.value == value:
                            parentNode.left = targetNode.right
                        else:
                            parentNode.right = targetNode.right
                    else:
                        self.root = targetNode.right

    def getParent(self, value):
        if self.hasRootNode():
            print("树为空")
        else:
            return self.root.getParentNode(value)


# 7,3,10,12,5,1,9
bst = BinarySortTree(Node(7))
bst.addNode(Node(3))
bst.addNode(Node(10))
bst.addNode(Node(12))
bst.addNode(Node(5))
bst.addNode(Node(1))
bst.addNode(Node(9))
bst.addNode(Node(2))
bst.preOrder()
print("=" * 20)
print(bst.searchNode(3))
print(bst.searchNode(7))
print(bst.searchNode(10))
print(bst.searchNode(12))
print(bst.searchNode(5))
print(bst.searchNode(1))
print(bst.searchNode(9))
print("=" * 20)
print(bst.getParent(7))
print(bst.getParent(3))
print(bst.getParent(10))
print(bst.getParent(12))
print(bst.getParent(5))
print(bst.getParent(1))
print(bst.getParent(9))

print("~" * 20)
# 测试删除叶子节点
# bst.delNode(1)
# bst.delNode(5)
# bst.delNode(9)
# bst.delNode(12)
# bst.delNode(10)
# bst.delNode(3)
# bst.delNode(7)

# 测试删除一个有叶子节点的节点
# bst.delNode(1)
# bst.delNode(2)
# bst.delNode(3)

# 测试删除有2个叶子节点的节点
bst.delNode(3)
bst.delNode(10)
bst.delNode(7)
bst.delNode(9)
bst.delNode(12)
bst.delNode(2)
bst.delNode(5)
bst.delNode(1)
bst.preOrder()
bst.addNode(Node(11))
bst.addNode(Node(22))
bst.preOrder()