平衡二叉树(AVL)python实现

AVL树是一种特殊的二叉搜索树 (BST树),数据极端情况下, 二叉搜索树会退化成为单链表,但是AVL树通过旋转操作规避了这个问题。

查找平均复杂度:O(logn)

# AVL树不适于删除的情况
class AVLTreeNode(object):
    def __init__(self, data):
        self.data = data  # 数据
        self.left: AVLTreeNode = None  # 左子树
        self.right: AVLTreeNode = None  # 右子树
        self.height = 1  # 树高度


def get_data(node: AVLTreeNode):
    return node.data


def set_data(node: AVLTreeNode, data):
    node.data = data


# 获得树形结构
def get_left_node(node: AVLTreeNode):
    return node.left


def get_right_node(node: AVLTreeNode):
    return node.right


def get_height(node: AVLTreeNode):
    if node is None:
        return 0
    return node.height


def get_max_node(node: AVLTreeNode):
    temp_node = node
    if temp_node.right is not None:
        return get_max_node(temp_node.right)
    else:
        return temp_node


def get_min_node(node: AVLTreeNode):
    temp_node = node
    if temp_node.left is not None:
        return get_min_node(temp_node.left)
    else:
        return temp_node


def get_node(node: AVLTreeNode, data):
    temp_node: AVLTreeNode = node
    while temp_node:
        if data < temp_node.data:
            temp_node = temp_node.left
        elif data > temp_node.data:
            temp_node = temp_node.right
        else:
            return temp_node
    return None


# 右旋:先记录待旋转节点的左节点,然后将左节点的right指向待旋转节点即可
def right_rotate(node: AVLTreeNode):
    head_node: AVLTreeNode = node.left
    node.left = head_node.right  # 将父节点的右侧放在待旋转节点的左侧
    head_node.right = node  # 将父节点的右指针指向待旋转节点
    node.height = max(get_height(node.left), get_height(node.right)) + 1
    head_node.height = max(get_height(head_node.left), get_height(head_node.right)) + 1
    return head_node


def left_rotate(node: AVLTreeNode):
    head_node: AVLTreeNode = node.right
    node.right = head_node.left
    head_node.left = node
    node.height = max(get_height(node.left), get_height(node.right)) + 1
    head_node.height = max(get_height(head_node.left), get_height(head_node.right)) + 1
    return head_node


# 先左旋,再右旋
def left_right_rotate(node: AVLTreeNode):
    son_node = left_rotate(node.left)
    node.left = son_node
    return right_rotate(node)


def right_left_rotate(node: AVLTreeNode):
    son_node = right_rotate(node.right)
    node.right = son_node
    return left_rotate(node)


# 左子树与右子树差距最大为1,否则及时调整
def adjust_height(node: AVLTreeNode):
    if get_height(node.right) - get_height(node.left) > 1:
        if get_height(node.right.right) > get_height(node.right.left):
            node = left_rotate(node)
        else:
            node = right_left_rotate(node)
    elif get_height(node.left) - get_height(node.right) > 1:
        if get_height(node.left.left) > get_height(node.left.right):
            node = right_rotate(node)
        else:
            node = left_right_rotate(node)
    else:
        pass
    return node


def insert_node(node: AVLTreeNode, data):
    if node is None:
        return AVLTreeNode(data)
    if (node.data is not None) and (data < node.data):  # 向左插入
        node.left = insert_node(node.left, data)
        node.height = max(get_height(node.left), get_height(node.right)) + 1
        node = adjust_height(node)
    elif (node.data is not None) and (data > node.data):  # 向右插入
        node.right = insert_node(node.right, data)
        node.height = max(get_height(node.left), get_height(node.right)) + 1
        node = adjust_height(node)
    else:
        print('Can not insert same value')
    return node


def delete_node(node: AVLTreeNode, data):
    if node is None:
        return None
    if (node is not None) and (data < node.data):  # 左侧查询
        node.left = delete_node(node.left, data)
        node = adjust_height(node)
    elif (node is not None) and (data > node.data):  # 右侧查询
        node.right = delete_node(node.right, data)
        node = adjust_height(node)
    else:  # 在这里删除
        if (node.left is not None) and (node.right is not None):  # 左右节点都不为空
            node.data = get_min_node(node.right).data
            node.right = delete_node(node.right, node.data)
        elif node.left is not None:  # 左节点不为空,右节点为空
            node = node.left
        else:  # 左节点为空,右节点未知
            node = node.right
    if node is not None:
        node.height = max(get_height(node.left), get_height(node.right)) + 1
        adjust_height(node)
    return node


def get_all(node: AVLTreeNode):
    values = []

    def add_values(values, node: AVLTreeNode):
        if node is not None:
            values = add_values(values, node.left)
            values.append(node.data)
            values = add_values(values, node.right)
        return values

    return add_values(values, node)


def main():
    root = AVLTreeNode(10)
    number_list = (3, 2, 1, 4, 5, 6, 7, 15, 26, 17)
    for number in number_list:
        root = insert_node(root, number)
    all_values = get_all(root)
    del_note = delete_node(root, 3)
    all_values = get_all(root)
    pass


if __name__ == '__main__':
    main()

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

呆萌的代Ma

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值