python 实现二叉搜索树的方法有哪些?

树的介绍

树不同于链表或哈希表,是一种非线性数据结构,树分为二叉树、二叉搜索树、B树、B+树、红黑树等等。

树是一种数据结构,它是由n个有限节点组成的一个具有层次关系的集合。用图片来表示的话,可以看到它很像一棵倒挂着的树。因此我们将这类数据结构统称为树,树根在上面,树叶在下面。一般的树具有以下特点:

  • 每个节点有0个或者多个子节点
  • 没有父节点的节点被称为根节点
  • 每个非根节点有且只有一个父节点
  • 每个子结点都可以分为多个不相交的子树

二叉树的定义是:每个节点最多有两个子节点。即每个节点只能有以下四种情况:

  1. 左子树和右子树均为空
  2. 只存在左子树
  3. 只存在右子树
  4. 左子树和右子树均存在

二叉搜索树

二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:

  • 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
  • 它的左右子树也分别为二叉搜索树

列举几种Python中几种常见的实现方式:

1.使用类和递归函数实现

通过定义一个节点类,包含节点值、左右子节点等属性,然后通过递归函数实现插入、查找、删除等操作。代码示例如下:

class Node:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
​
class BST:
    def __init__(self):
        self.root = None
​
    def insert(self, value):
        if self.root is None:
            self.root = Node(value)
        else:
            self._insert(value, self.root)
​
    def _insert(self, value, node):
        if value < node.data:
            if node.left is None:
                node.left = Node(value)
            else:
                self._insert(value, node.left)
        elif value > node.data:
            if node.right is None:
                node.right = Node(value)
            else:
                self._insert(value, node.right)
​
    def search(self, value):
        if self.root is None:
            return False
        else:
            return self._search(value, self.root)
​
    def _search(self, value, node):
        if node is None:
            return False
        elif node.data == value:
            return True
        elif value < node.data:
            return self._search(value, node.left)
        else:
            return self._search(value, node.right)
​
    def delete(self, value):
        if self.root is None:
            return False
        else:
            self.root = self._delete(value, self.root)
​
    def _delete(self, value, node):
        if node is None:
            return node
        elif value < node.data:
            node.left = self._delete(value, node.left)
        elif value > node.data:
            node.right = self._delete(value, node.right)
        else:
            if node.left is None and node.right is None:
                del node
                return None
            elif node.left is None:
                temp = node.right
                del node
                return temp
            elif node.right is None:
                temp = node.left
                del node
                return temp
            else:
                temp = self._find_min(node.right)
                node.data = temp.data
                node.right = self._delete(temp.data, node.right)
        return node
​
    def _find_min(self, node):
        while node.left is not None:
            node = node.left
        return node

2.使用列表实现

通过使用一个列表来存储二叉搜索树的元素,然后通过列表中元素的位置关系来实现插入、查找、删除等操作。代码示例如下:

class BST:
    def __init__(self):
        self.values = []
​
    def insert(self, value):
        if len(self.values) == 0:
            self.values.append(value)
        else:
            self._insert(value, 0)
​
    def _insert(self, value, index):
        if value < self.values[index]:
            left_child_index = 2 * index + 1
            if left_child_index >= len(self.values):
                self.values.extend([None] * (left_child_index - len(self.values) + 1))
            if self.values[left_child_index] is None:
                self.values[left_child_index] = value
            else:
                self._insert(value, left_child_index)
        else:
            right_child_index = 2 * index + 2
            if right_child_index >= len(self.values):
                self.values.extend([None] * (right_child_index - len(self.values) + 1))
            if self.values[right_child_index] is None:
                self.values[right_child_index] = value
            else:
                self._insert(value, right_child_index)
​
    def search(self, value):
        if value in self.values:
            return True
        else:
            return False
​
    def delete(self, value):
        if value not in self.values:
            return False
        else:
            index = self.values.index(value)
            self._delete(index)
            return True
​
    def _delete(self, index):
        left_child_index = 2 * index + 1
        right_child_index = 2 * index + 2
        if left_child_index < len(self.values) and self.values[left_child_index] is not None:
            self._delete(left_child_index)
        if right_child_index < len(self.values) and self.values[right_child_index] is not None:
            self

3.使用字典实现

其中字典的键表示节点值,字典的值是一个包含左右子节点的字典。代码示例如下:

def insert(tree, value):
    if not tree:
        return {value: {}}
    elif value < list(tree.keys())[0]:
        tree[list(tree.keys())[0]] = insert(tree[list(tree.keys())[0]], value)
    else:
        tree[list(tree.keys())[0]][value] = {}
    return tree
​
def search(tree, value):
    if not tree:
        return False
    elif list(tree.keys())[0] == value:
        return True
    elif value < list(tree.keys())[0]:
        return search(tree[list(tree.keys())[0]], value)
    else:
        return search(tree[list(tree.keys())[0]].get(value), value)
​
def delete(tree, value):
    if not search(tree, value):
        return False
    else:
        if list(tree.keys())[0] == value:
            if not tree[list(tree.keys())[0]]:
                del tree[list(tree.keys())[0]]
            elif len(tree[list(tree.keys())[0]]) == 1:
                tree[list(tree.keys())[0]] = list(tree[list(tree.keys())[0]].values())[0]
            else:
                min_key = min(list(tree[list(tree.keys())[0]+1].keys()))
                tree[min_key] = tree[list(tree.keys())[0]+1][min_key]
                tree[min_key][list(tree.keys())[0]] = tree[list(tree.keys())[0]]
                del tree[list(tree.keys())[0]]
        elif value < list(tree.keys())[0]:
            tree[list(tree.keys())[0]] = delete(tree[list(tree.keys())[0]], value)
        else:
            tree[list(tree.keys())[0]][value] = delete(tree[list(tree.keys())[0]].get(value), value)
    return tree

由于字典是无序的,因此该实现方式可能会导致二叉搜索树不平衡,影响插入、查找和删除操作的效率。

4.使用堆栈实现

使用堆栈(Stack)可以实现一种简单的二叉搜索树,可以通过迭代方式实现插入、查找、删除等操作。具体实现过程如下:

  1. 定义一个节点类,包含节点值、左右子节点等属性。
  2. 定义一个堆栈,初始时将根节点入栈。
  3. 当栈不为空时,取出栈顶元素,并对其进行操作:如果要插入的值小于当前节点值,则将要插入的值作为左子节点插入,并将左子节点入栈;如果要插入的值大于当前节点值,则将要插入的值作为右子节点插入,并将右子节点入栈;如果要查找或删除的值等于当前节点值,则返回或删除该节点。
  4. 操作完成后,继续从堆栈中取出下一个节点进行操作,直到堆栈为空。

需要注意的是,在这种实现方式中,由于使用了堆栈来存储遍历树的过程,因此可能会导致内存占用较高。另外,由于堆栈的特性,这种实现方式只能支持深度优先遍历(Depth-First Search,DFS),不能支持广度优先遍历(Breadth-First Search,BFS)。

以下是伪代码示例:

class Node:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
​
def insert(root, value):
    if not root:
        return Node(value)
    stack = [root]
    while stack:
        node = stack.pop()
        if value < node.data:
            if node.left is None:
                node.left = Node(value)
                break
            else:
                stack.append(node.left)
        elif value > node.data:
            if node.right is None:
                node.right = Node(value)
                break
            else:
                stack.append(node.right)
​
def search(root, value):
    stack = [root]
    while stack:
        node = stack.pop()
        if node.data == value:
            return True
        elif value < node.data and node.left:
            stack.append(node.left)
        elif value > node.data and node.right:
            stack.append(node.right)
    return False
​
def delete(root, value):
    if root is None:
        return None
    if value < root.data:
        root.left = delete(root.left, value)
    elif value > root.data:
        root.right = delete(root.right, value)
    else:
        if root.left is None:
            temp = root.right
            del root
            return temp
        elif root.right is None:
            temp = root.left
            del root
            return temp
        else:
            temp = root.right
            while temp.left is not None:
                temp = temp.left
            root.data = temp.data
            root.right = delete(root.right, temp.data)
    return root

以上是四种在Python中实现二叉搜索树的方法,在具体使用过程中还是需要合理选择,尽量以运行速度快、内存占用少为出发点,最后觉得有帮助的话请多多关注和赞同!!!

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.kler.cn/a/8173.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Unity中将项目通用的公共模块封装成类库dll

前言&#xff1a; 最近公司的App项目开始用Unity来开发了&#xff0c;可能大家好奇为什么不用原生的AndroidStudio来开发&#xff0c;主要原因是因为我们做的都是医疗类的App&#xff0c;里面或多或少都用到了Unity虚拟场景&#xff0c;以前我们都是采用Android集成Unity来满足…

如何让chatGPT变成中文-ChatGPT怎么完整输出

ChatGPT厉害在哪 ChatGPT 厉害在于它是使用深度学习技术进行训练的大型神经网络模型&#xff0c;可以从大量的自然语言数据中自动学习语言模式、词汇和语法规则&#xff0c;从而生成相对流畅和准确的文本。以下是 ChatGPT 的主要优势&#xff1a; 可以根据输入自动进行语言生成…

Spark 之 解析json的复杂和嵌套数据结构

本文主要使用以下几种方法&#xff1a; 1&#xff0c;get_json_object()&#xff1a;从一个json 字符串中根据指定的json 路径抽取一个json 对象 2&#xff0c;from_json()&#xff1a;从一个json 字符串中按照指定的schema格式抽取出来作为DataFrame的列 3&#xff0c;to_j…

身临其境数字世界:探索VR全景元宇宙展厅

随着科技的不断发展&#xff0c;虚拟现实技术已经成为我们生活中的一部分。VR全景元宇宙展厅作为其中的一种形式&#xff0c;正越来越受欢迎。在这里&#xff0c;您可以探索未知的世界&#xff0c;体验全新的视觉和感官体验。 一、VR全景元宇宙展厅的概述 VR全景元宇宙展厅是一…

前端学习:HTML链接

目录 一、HTML超链接&#xff08;链接&#xff09; 二、HTML链接语法 三、target属性 target属性值展示 四、name属性 五、补充 关于创建电子邮件链接时如何发送邮件内容 在进行抄送时&#xff0c;需要使用关键字&#xff1a;cc 在进行密送时&#xff0c;需要使用关键字&a…

Linux小黑板(14):基于环形队列的生成消费者模型

"多少人都&#xff0c;生来纯洁完美&#xff0c;心底从不染漆黑。" 我们先来瞅瞅我们之前基于阻塞队列的生产消费者模型代码。 void Push(const T& in){// 生产任务pthread_mutex_lock(&_mutex);while(is_full()){pthread_cond_wait(&_pcond,&_mute…

4款【新概念APP】对比+免费下载

4款【新概念APP】对比免费下载4款【新概念APP】对比免费下载新概念英语咖&#xff08;体积小、无广告、全免费、不能倍速播放&#xff09;新概念英语全册&#xff08;免费&#xff0c;但强制广告&#xff0c;否则不能播放音频。可以倍速&#xff09;新概念英语全四册&#xff0…

【开发工程师的运维小知识】docker安装gitlab

文章目录1 搜索gitlab的镜像2 拉取gitlab镜像3 创建挂载目录4 创建gitlab容器并启动5 查看是否启动成功6 修改配置文件7 重启gitlab8 获取root初始化密码9 修改root初始密码&#xff08;可选&#xff09;进入docker-gitlab容器内部打开控制台查找第一个User&#xff08;这个就是…

【SQL Server】数据库开发指南(一)数据库设计

文章目录一、数据库设计的必要性二、什么是数据库设计三、数据库设计的重要性五、数据模型5.1 实体-关系&#xff08;E-R&#xff09;数据模型5.2 实体&#xff08;Entity&#xff09;5.3 属性&#xff08;Attribute&#xff09;5.5 关系&#xff08;Relationship&#xff09;六…

生成式人工智能所面临的问题有哪些?

在生成式人工智能中工作需要混合技术、创造性和协作技能。通过发展这些技能&#xff0c;您将能够在这个令人兴奋且快速发展的领域应对具有挑战性的问题。 生成式人工智能是指一类机器学习技术&#xff0c;旨在生成与训练数据相似但不完全相同的新数据。 换句话说&#xff0c;…

苹果6信号不好的快速解决方法

许多朋友反馈&#xff0c;苹果6的信号不佳&#xff0c;建议从以下方面查找&#xff1a; 方法一&#xff1a;开启飞行模式后再关闭 有时候手机由于周围环境网络比较差&#xff0c;会导致信号处于无服务状态&#xff0c;这时后我们开启飞行模式后再关闭飞行模式&#xff0c;系统就…

【多线程与高并发(锁)】1、锁的概念、分类和状态

1、锁的概念 java当中的锁、是在多线程环境下为保证共享资源健康、线程安全的一种手段。 线程操作某个共享资源之前&#xff0c;先对资源加一层锁&#xff0c;保证操作期间没有其他线程访问资源&#xff0c;当操作完成后&#xff0c;再释放锁。 2、锁的分类 Java中的锁按照…

Obsidian:实现日记记录【设计并使用模板】

问题背景 我是一个比较喜欢记录的人&#xff0c;有一定的写日记的习惯的&#xff0c;但是我又不太喜欢将自己的个人的数据寄人篱下&#xff0c;放在别人的数据库中。 于是就想着将自己的日记存放在自己本地的磁盘中…… 在一次偶然在B站中翻找资料时&#xff0c;我发现了这个…

Linux-Shell设计

一、shell 总论 ​ shell 就是“壳程序”&#xff0c;这个名字是针对 kernel 来说的&#xff0c;也就是在操作系统外围的程序&#xff08;严格的讲&#xff0c;已经不是操作系统了&#xff09;。宏观上的 shell 是所有的应用程序&#xff0c;而狭义上的 shell&#xff0c;指的…

STM32CubeMXA安装和创建项目

STM32CubeMXA安装和创建项目 安装STM32CubeMXA STM32CubeMX 运行环境搭建包含两个部分。首先是 Java 运行环境安装&#xff0c;其次是 STM32CubeMX 软件安装。 安装 JAVA 环境 对于 Java 运行环境&#xff0c;大家可以到 Java 官网 www.java.com 下载最新的 Java 软件 安装…

CSS 扫盲

✏️作者&#xff1a;银河罐头 &#x1f4cb;系列专栏&#xff1a;JavaEE &#x1f332;“种一棵树最好的时间是十年前&#xff0c;其次是现在” 目录引入方式内部样式内联样式外部样式CSS 选择器CSS 常用属性值字体属性设置字体大小粗细文字样式文本属性文本颜色文本对齐文本装…

使用Jmeter进行http接口测试

前言&#xff1a; 本文主要针对http接口进行测试&#xff0c;使用Jmeter工具实现。 Jmter工具设计之初是用于做性能测试的&#xff0c;它在实现对各种接口的调用方面已经做的比较成熟&#xff0c;因此&#xff0c;本次直接使用Jmeter工具来完成对Http接口的测试。 一、开发接口…

【Unity项目实战】从零手戳一个背包系统

首先我们下载我们的人物和背景资源,因为主要是背包系统,所以人物的移动和场景的搭建这里我们就不多讲了,我这里直接提供基础项目源码给大家去使用就行 基础项目下载地址: 链接: https://pan.baidu.com/s/1o7_RW_QQ1rrAbDzT69ApRw 提取码: 8s95 顺带说一下,这里用到了uni…

uniCloud开发api接口服务

首先创建一个云对象&#xff1a; 在创建的云对象的index.Obj.js中进行编码&#xff1a; const db uniCloud.database() module.exports {_before: function () { // 通用预处理器},async get(){//demo-user 是云数据中的一个表名let res await db.collection("demo-us…

最易学和最难学编程语言排行榜!

如果问一个程序员最容易学习的语言&#xff0c;就像问一个人他们最喜欢的冰淇淋。每个人都有自己的偏好&#xff0c;永远没有真正的正确答案。 正如开发者和教育家 Marek Zaluski 曾经说的那样&#xff0c;"编程语言是由程序员创造的&#xff0c;为程序员服务"。这几…
最新文章