Python实现二叉排序树与平衡二叉树的示例代码

现在让我们来详细讲解如何使用Python实现二叉排序树与平衡二叉树。

二叉排序树

二叉排序树(BST)是一种特殊的二叉树,它的每个节点最多有两个子节点,左子节点的值比父节点小,右子节点的值比父节点大。因此,二叉排序树可以很好地存储和快速查找有序数据。

实现过程

  1. 定义节点类

我们首先需要定义二叉排序树的节点类,它至少需要包含以下属性:

  • value:存储节点的值
  • left:存储左子节点的引用
  • right:存储右子节点的引用
class TreeNode:
    def __init__(self, value):
        self.value = value
        self.left = None
        self.right = None
  1. 插入节点

对于一个没有任何节点的空树,我们将插入第一个节点作为根节点,否则我们需要通过递归查找合适的插入位置。

def insert_node(root, value):
    if root is None:
        root = TreeNode(value)
    elif root.value > value:
        root.left = insert_node(root.left, value)
    elif root.value < value:
        root.right = insert_node(root.right, value)
    return root
  1. 删除节点

删除节点是二叉排序树中比较常见的操作,我们需要实现以下两个删除节点的函数:

  • 查找待删除节点
  • 删除节点
def find_node(root, value):
    if root is None or root.value == value:
        return root
    elif root.value > value:
        return find_node(root.left, value)
    else:
        return find_node(root.right, value)


def delete_node(root, value):
    if root is None:
        return root
    if root.value == value:
        if root.left is None:
            return root.right
        elif root.right is None:
            return root.left
        else:
            min_node = find_min_node(root.right)
            root.value = min_node.value
            root.right = delete_node(root.right, min_node.value)
    elif root.value > value:
        root.left = delete_node(root.left, value)
    else:
        root.right = delete_node(root.right, value)
    return root


def find_min_node(root):
    while root.left is not None:
        root = root.left
    return root

示例

现在让我们通过一个示例来理解二叉排序树的使用。

我们现在有一组数据[5, 6, 2, 8, 3, 1, 4],我们可以通过以下代码将它们插入二叉排序树中并进行中序遍历来验证插入操作是否正确。

def inorder_traverse(root, values):
    if root is not None: 
        inorder_traverse(root.left, values) 
        values.append(root.value) 
        inorder_traverse(root.right, values) 
    return values


if __name__ == '__main__':
    nums = [5, 6, 2, 8, 3, 1, 4]
    root = None
    for num in nums:
        root = insert_node(root, num)
    res = inorder_traverse(root, [])
    print(res)   # [1, 2, 3, 4, 5, 6, 8]
    root = delete_node(root, 5)
    res = inorder_traverse(root, [])
    print(res)   # [1, 2, 3, 4, 6, 8]

注意我们还演示了删除节点的操作。

平衡二叉树

平衡二叉树(AVL Tree)是一种二叉排序树,但相比于二叉排序树,它的左右子树的高度差不能超过1,这样可以确保树的高度平衡,插入和查找操作的时间复杂度可以保证在O(logn)。

实现过程

平衡二叉树实现起来比较复杂,我们需要先了解如何计算平衡因子,并实现旋转操作。

  1. 计算平衡因子

平衡因子:左子树的高度减去右子树的高度。

我们可以通过以下代码计算节点的平衡因子:

def get_height(root):
    if root is None:
        return 0
    return max(get_height(root.left), get_height(root.right)) + 1


def get_balance_factor(root):
    if root is None:
        return 0
    return get_height(root.left) - get_height(root.right)
  1. 实现旋转操作

旋转操作可以分为左旋和右旋两种,它们可以帮助我们调整平衡二叉树,使得节点的平衡因子恢复为-1、0或1。

def left_rotate(root):
    right_node = root.right
    root.right = right_node.left
    right_node.left = root
    return right_node


def right_rotate(root):
    left_node = root.left
    root.left = left_node.right
    left_node.right = root
    return left_node
  1. 插入节点

对于一个没有任何节点的空树,我们将插入第一个节点作为根节点,否则我们需要通过递归查找合适的插入位置。

插入节点之后,我们需要检查是否需要通过旋转操作来调整平衡。

def insert_node(root, value):
    if root is None:
        root = TreeNode(value)
    elif root.value > value:
        root.left = insert_node(root.left, value)
    elif root.value < value:
        root.right = insert_node(root.right, value)
    # 更新平衡因子
    balance_factor = get_balance_factor(root)
    # LL
    if balance_factor > 1 and value < root.left.value:
        return right_rotate(root)
    # RR
    elif balance_factor < -1 and value > root.right.value:
        return left_rotate(root)
    # LR
    elif balance_factor > 1 and value > root.left.value:
        root.left = left_rotate(root.left)
        return right_rotate(root)
    # RL
    elif balance_factor < -1 and value < root.right.value:
        root.right = right_rotate(root.right)
        return left_rotate(root)
    return root

示例

现在让我们通过一个示例来理解平衡二叉树的使用。

我们现在有一组数据[5, 6, 2, 8, 3, 1, 4],我们可以通过以下代码将它们插入平衡二叉树中并进行中序遍历来验证插入操作是否正确。

if __name__ == '__main__':
    nums = [5, 6, 2, 8, 3, 1, 4]
    root = None
    for num in nums:
        root = insert_node(root, num)
    res = inorder_traverse(root, [])
    print(res)   # [1, 2, 3, 4, 5, 6, 8]
    root = delete_node(root, 5)
    res = inorder_traverse(root, [])
    print(res)   # [1, 2, 3, 4, 6, 8]

注意我们通过AVL Tree保证了二叉树的高度平衡,因此对于同样的数据,我们可以得到不同的高度,这可以节省查找操作的时间复杂度。

以上是二叉排序树与平衡二叉树的Python实现攻略,希望对你有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python实现二叉排序树与平衡二叉树的示例代码 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • MySQL验证用户权限的方法

    MySQL验证用户权限的方法首先需要了解MySQL的权限体系及其相关概念: 用户:连接MySQL数据库系统的用户。 主机:连接MySQL数据库系统的客户机所在的主机。 权限:用户对某个主机上某个数据库执行某个操作的权限。 而MySQL权限体系中包含如下权限: ALL PRIVILEGES:所有权限。 CREATE:创建数据库和表。 DROP:删除数据库和表。…

    other 2023年6月27日
    00
  • knockoutjs快速入门(经典)

    KnockoutJS快速入门(经典) KnockoutJS是一款流行的JavaScript框架,用于构建动态的Web应用程序。它采用MVVM(Model-View-ViewModel)模式,可以将数据模型和视图分离,使得开发员可以更加专注于业务逻辑的实现。本文将介绍KnockoutJS的快速入门,包括如何创建ViewModel、如何绑定数据和如何处理用户交互…

    other 2023年5月9日
    00
  • 网线ip总是冲突怎么办 网线连上后提示IP地址冲突的解决方法

    网线IP总是冲突的解决方法攻略 当网线连接上后提示IP地址冲突时,这可能是因为多个设备在同一网络上使用了相同的IP地址。为了解决这个问题,你可以采取以下步骤: 步骤一:确认IP地址冲突 首先,你需要确认是否真的存在IP地址冲突。你可以按照以下步骤进行确认: 打开命令提示符(Windows)或终端(Mac和Linux)。 输入命令 ipconfig(Windo…

    other 2023年7月30日
    00
  • 怎么解压文件

    当我们从网络或其他地方下载了一个压缩文件时,需要解压文件才能使用其中的内容。下面是解压文件的完整攻略。 1. 下载压缩文件 首先,需要下载压缩文件到本地计算机。可以从网站、FTP服务器和其他渠道下载。 2. 确认压缩文件格式 要正确地解压缩文件,需要知道它的格式。目前常见的压缩文件格式有.zip、.rar、.tar、.gz等,还有一些特殊的格式。根据文件的扩…

    其他 2023年4月16日
    00
  • formdata请求接口传递参数格式

    formdata请求接口传递参数格式 在前后端交互的过程中,我们常常需要使用ajax请求来向服务端发送数据。其中,常用的一种传参方式就是FormData。本文将详细介绍FormData的使用方法以及注意事项。 什么是FormData FormData 是一种表单序列化的方式,用于将表单数据格式化为 key/value 的形式,从而方便地用于ajax异步请求。…

    其他 2023年3月28日
    00
  • Bootstrap布局之栅格系统学习笔记

    Bootstrap布局之栅格系统学习笔记 什么是栅格系统? 栅格系统是Bootstrap框架中的一个重要组成部分,用于创建响应式的网页布局。它将页面水平划分为12个等宽的列,开发者可以根据需要将内容放置在这些列中,从而实现灵活的布局。 栅格系统的基本结构 栅格系统由行(row)和列(column)组成。行用于包含列,而列则用于放置内容。以下是栅格系统的基本结…

    other 2023年7月28日
    00
  • 详解MySQL InnoDB存储引擎的内存管理

    详解MySQL InnoDB存储引擎的内存管理 MySQL InnoDB存储引擎是MySQL数据库中最常用的存储引擎之一。它具有高性能和可靠性,并且提供了强大的内存管理功能。本攻略将详细讲解MySQL InnoDB存储引擎的内存管理,包括内存池、缓冲池和日志缓冲等方面。 1. 内存池(Buffer Pool) 内存池是InnoDB存储引擎中最重要的内存组件之…

    other 2023年8月1日
    00
  • 如何在 Illustrator 中创建图案

    如何在 Illustrator 中创建图案 Illustrator 是一款功能强大的矢量图形编辑软件,可以用来创建各种图案。下面是在 Illustrator 中创建图案的详细攻略。 步骤一:创建基本图形 打开 Illustrator 软件,并创建一个新的文档。 使用绘图工具(如矩形工具、椭圆工具等)创建基本图形,可以根据需要选择填充颜色和边框样式。 示例说明…

    other 2023年10月15日
    00
合作推广
合作推广
分享本页
返回顶部