python 实现二叉搜索树的四种方法

Python 实现二叉搜索树的四种方法

二叉搜索树(Binary Search Tree,简称BST)是一棵二叉树,它具有以下性质:

  1. 若左子树不为空,则左子树上所有结点的值均小于它的根节点的值;
  2. 若右子树不为空,则右子树上所有结点的值均大于它的根节点的值;
  3. 左、右子树分别也为二叉搜索树;
  4. 没有键值相等的节点;

因其高效性,在排序、查找等问题中,常常使用二叉搜索树来解决。下面,我们将介绍python中四种二叉搜索树的实现。

1. Python实现简单二叉搜索树

在BST的实现中,节点对象包含“val“、”left”和”right”三个域,其中”val“表示节点的值,”left”和”right”分别指向左右子树。get()方法用来查找值,insert()方法用来插入新节点。

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

class BinarySearchTree:
    def __init__(self):
        self.root = None

    def get(self, val):
        if self.root is None:
            return None
        else:
            return self._get(val, self.root)

    def _get(self, val, cur_node):
        if cur_node.val == val:
            return cur_node
        elif val < cur_node.val and cur_node.left is not None:
            return self._get(val, cur_node.left)
        elif val > cur_node.val and cur_node.right is not None:
            return self._get(val, cur_node.right)
        else:
            return None

    def insert(self, val):
        if self.root is None:
            self.root = Node(val)
        else:
            self._insert(val, self.root)

    def _insert(self, val, cur_node):
        if val < cur_node.val:
            if cur_node.left is None:
                cur_node.left = Node(val)
            else:
                self._insert(val, cur_node.left)
        elif val > cur_node.val:
            if cur_node.right is None:
                cur_node.right = Node(val)
            else:
                self._insert(val, cur_node.right)
        else:
            print('Value already in tree.')

下面给出一个简单例子,创建一棵二叉搜索树并插入一些新值:

tree = BinarySearchTree()
tree.insert(6)
tree.insert(3)
tree.insert(9)
tree.insert(2)
tree.insert(4)
tree.insert(8)
tree.insert(10)

2. Python实现AVL树

AVL树是一种自平衡的二叉搜索树,在应用于高并发、高IO、高负载的情况下可以减少树的深度,从而提升搜索的效率。与简单二叉搜索树不同,AVL树可以旋转来自平衡,保证在对一组n个数据进行建树之后的深度总是O(logn)。

class Node:
    def __init__(self, val):
        self.left = None
        self.right = None
        self.val = val
        self.height = 1

class AVLTree:
    def __init__(self):
        self.root = None

    def _get_height(self, node):
        if not node:
            return 0
        return node.height

    def _get_balance(self, node):
        if not node:
            return 0
        return self._get_height(node.left) - self._get_height(node.right)

    def _fix_height(self, node):
        node.height = 1 + max(self._get_height(node.left),
                              self._get_height(node.right))

    def _right_rotate(self, y):
        x = y.left
        T2 = x.right

        x.right = y
        y.left = T2

        self._fix_height(y)
        self._fix_height(x)

        return x

    def _left_rotate(self, x):
        y = x.right
        T2 = y.left

        y.left = x
        x.right = T2

        self._fix_height(x)
        self._fix_height(y)

        return y

    def insert(self, val):
        def _insert(node, val):
            if not node:
                return Node(val)
            elif val < node.val:
                node.left = _insert(node.left, val)
            elif val > node.val:
                node.right = _insert(node.right, val)
            else:
                return node

            self._fix_height(node)

            balance = self._get_balance(node)

            if balance > 1 and val < node.left.val:
                return self._right_rotate(node)

            if balance < -1 and val > node.right.val:
                return self._left_rotate(node)

            if balance > 1 and val > node.left.val:
                node.left = self._left_rotate(node.left)
                return self._right_rotate(node)

            if balance < -1 and val < node.right.val:
                node.right = self._right_rotate(node.right)
                return self._left_rotate(node)

            return node

        self.root = _insert(self.root, val)

下面给出一个简单例子,创建一棵AVL树并插入一些新值:

tree = AVLTree()

tree.insert(9)
tree.insert(5)
tree.insert(10)
tree.insert(0)
tree.insert(6)
tree.insert(11)
tree.insert(-1)
tree.insert(1)
tree.insert(2)

3. Python实现红黑树

红黑树也是自平衡的二叉搜索树。它通过颜色标记节点来保证在一组n个数据中经过建树之后深度总是O(logn)。

RED = True
BLACK = False

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

class RedBlackTree:
    def __init__(self):
        self.root = None

    @staticmethod
    def _color(node):
        if node is None:
            return BLACK
        else:
            return node.color

    def _rotate_left(self,node):
        right_node=node.right
        node.right= right_node.left
        right_node.left= node
        right_node.color= node.color
        node.color= RED
        return right_node

    def _rotate_right(self,node):
        left_node= node.left
        node.left= left_node.right
        left_node.right= node
        left_node.color= node.color
        node.color= RED
        return left_node

    def _flip_color(self,node):
        node.color= RED
        node.left.color= BLACK
        node.right.color= BLACK

    def insert(self, val):

        def _insert(node, val):
            if not node:
                return Node(val, RED)

            if val < node.val:
                node.left = _insert(node.left, val)
            elif val > node.val:
                node.right = _insert(node.right, val)

            if self._color(node.right) == RED and self._color(node.left) == BLACK:
                node = self._rotate_left(node)

            if self._color(node.left) == RED and self._color(node.left.left) == RED:
                node = self._rotate_right(node)

            if self._color(node.left) == RED and self._color(node.right) == RED:
                self._flip_color(node)

            return node

        self.root = _insert(self.root, val)
        self.root.color = BLACK

下面给出一个简单例子,创建一棵红黑树并插入一些新值:

tree = RedBlackTree()

tree.insert(9)
tree.insert(5)
tree.insert(10)
tree.insert(0)
tree.insert(6)
tree.insert(11)
tree.insert(-1)
tree.insert(1)
tree.insert(2)

4. Python实现B树

B树是一种多路平衡查找树,本质上是一个多叉排序树,可以用来解决大数据量的存储和索引问题。B树的特点是每个节点可以有多个儿子,如2-3树一样保持平衡,既能够保证查询效率,又能够提供插入和删除的功能。

class Node:
    def __init__(self, t, leaf=False):
        self.t = t
        self.keys = []
        self.children = []
        self.leaf = leaf

    def split(self, parent, i):
        t = self.t
        new_node = Node(t, leaf=self.leaf)
        parent.children.insert(i + 1, new_node)
        parent.keys.insert(i, self.keys[t - 1])
        new_node.children = self.children[t:]
        self.children = self.children[:t - 1]
        new_node.keys = self.keys[t:]
        self.keys = self.keys[:t - 1]
        return parent

    def insert(self, k):
        i = len(self.keys) - 1
        if self.leaf:
            self.keys.append(None)
            while i >= 0 and k < self.keys[i]:
                self.keys[i + 1] = self.keys[i]
                i -= 1
            self.keys[i + 1] = k
            return self, None
        else:
            while i >= 0 and k < self.keys[i]:
                i -= 1
            i += 1
            if len(self.children[i].keys) == 2 * self.t - 1:
                return self.children[i].insert(k).split(self, i)
            else:
                return self.children[i].insert(k), None

class BTree:
    def __init__(self, t=2):
        self.t = t
        self.root = Node(t, leaf=True)

    def search(self, k):
        x = self.root
        while x is not None:
            i = 0
            while i < len(x.keys) and k > x.keys[i]:
                i += 1
            if i < len(x.keys) and k == x.keys[i]:
                return x
            if x.leaf:
                return None
            else:
                x = x.children[i]
        return None

    def insert(self, k):
        node, split = self.root.insert(k)
        if split is not None:
            self.root = Node(self.t, leaf=False)
            self.root.children = [node, split]
            self.root.keys = [split.keys[0]]

下面给出一个简单例子,创建一棵B树并插入一些新值:

tree = BTree(2)

for i in range(1, 11):
    tree.insert(i)

search_val = 8

if tree.search(search_val):
    print("{} is found in the B-tree".format(search_val))
else:
    print("{} is not found in the B-tree".format(search_val))

# Output: 8 is found in the B-tree

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python 实现二叉搜索树的四种方法 - Python技术站

(0)
上一篇 2023年5月13日
下一篇 2023年5月13日

相关文章

  • 基于打开pycharm有带图片md文件卡死问题的解决

    针对“基于打开pycharm有带图片md文件卡死问题”的解决方案,我们可以尝试以下两种方法: 方法一:调整pycharm编辑器设置 打开Pycharm编译器,进入Settings(或Preferences)- Editor – General; 在“Editor Tabs”一栏中,找到“Tab Appearance”; 将 “Tab Limit” 值调整为合…

    python 2023年5月20日
    00
  • Pytorch中transforms.Resize()的简单使用

    下面是关于PyTorch中transforms.Resize()函数的详细讲解。 1. transforms.Resize()函数概述 transforms.Resize()函数是PyTorch中transforms模块提供的一个图像处理函数,它可以对图像进行缩放操作。具体来说,这个函数可以将输入图像的尺寸调整为给定的目标尺寸。 该函数的输入参数包括目标尺寸…

    python 2023年5月19日
    00
  • python如何遍历指定路径下所有文件(按按照时间区间检索)

    要实现Python遍历指定路径下所有文件并按照时间区间检索,可以使用os模块和datetime模块。 具体步骤如下: 步骤一:导入模块 import os import datetime 步骤二:定义函数 def search_files(start_dir, days): for dirpath, dirnames, filenames in os.wal…

    python 2023年6月3日
    00
  • Flask response响应的具体使用

    下面是关于Flask中响应的具体使用的完整攻略。 1. 使用Flask响应对象 当Flask应用需要返回响应时,可以使用Flask中自带的响应对象。常见的响应对象类型有: Response: 基础响应对象,可以设置状态码、响应头等。 make_response(): 使用Response对象创建响应。 jsonify(): 将字典或列表序列化成JSON格式的…

    python 2023年5月14日
    00
  • python使用xauth方式登录饭否网然后发消息

    首先我们来讲一下“python使用xauth方式登录饭否网然后发消息”的完整攻略。 1. 前置准备 1.1 注册饭否账号 如果你还没有饭否账号,需要先去饭否官网进行注册。 1.2 创建应用 登录饭否开发者平台创建一个新的应用,获取应用的consumer_key和consumer_secret。 1.3 安装依赖库 使用Python需要安装requests和o…

    python 2023年6月3日
    00
  • Python 批量验证和添加手机号码为企业微信联系人

    下面是关于“Python 批量验证和添加手机号码为企业微信联系人”的攻略: 步骤一:准备工作 在开始编写Python代码之前,我们需要做一些准备工作: 首先,如果您还没有企业微信账号,请在企业微信官网注册并创建一个企业。 登录企业微信,创建一个应用,并获取对应的AgentId和Secret。 安装需要使用的Python库:requests、json。 步骤二…

    python 2023年6月5日
    00
  • Python3 用什么IDE开发工具比较好

    下面是针对“Python3 用什么IDE开发工具比较好”的完整攻略。 什么是IDE开发工具 IDE全称是Integrated Development Environment,翻译成中文是“集成开发环境”,是一种集成了代码编辑器、编译器、调试器及其他有用的开发工具的软件环境,可以提高开发效率和开发质量。 Python3常用IDE开发工具 以下是几种常用的Pyt…

    python 2023年5月20日
    00
  • 基于python实现微信模板消息

    下面是详细的“基于Python实现微信模板消息”的攻略。 什么是微信模板消息 微信模板消息是一种可以在微信公众号上向用户发送固定格式消息的功能。通过模板消息,公众号可以向用户发送包括订单通知、支付通知、物流通知等各种消息,提高用户体验。模板消息需要在公众号后台进行配置和审核,审核成功后才能使用。 准备工作 在实现微信模板消息功能之前,需要先完成以下准备工作:…

    python 2023年6月3日
    00
合作推广
合作推广
分享本页
返回顶部