备战蓝桥杯Day25 - 二叉搜索树

news2024/11/18 4:25:23

一、基本概念

二叉搜索树(Binary Search Tree),又称为二叉查找树或二叉排序树,是一种具有特定性质的二叉树。

  1. 定义:二叉搜索树可以是一棵空树,也可以是具有以下特性的非空二叉树:

    • 若其左子树不空,则左子树上所有结点的值均小于其根结点的值。
    • 若其右子树不空,则右子树上所有结点的值均大于其根结点的值。
    • 它的左、右子树也分别为二叉排序树。
  2. 结构:二叉搜索树是以二叉树的形式组织的,通常可以使用链表数据结构来表示。每个结点除了包含关键字(key)和可能的其他数据外,还包含指向其左孩子(lchild)和右孩子(rchild)的指针,以及指向其父结点(parent)的指针(如果需要的话)。如果某个孩子结点或父结点不存在,则相应属性的值为空(NIL)。

  3. 元素特性:二叉搜索树中存储的元素必须具备可比较性,例如整数(int)或浮点数(double)等。如果是自定义类型,需要指定比较方式。

  4. 应用:二叉搜索树作为一种经典的数据结构,具有链表快速插入与删除操作的特点和数组快速查找的优势。因此,它在许多场合下都有广泛的应用,如在文件系统和数据库系统中用于高效的排序与检索操作。

二叉搜索树是一种非常有效的数据结构,它能够保持数据的有序性,同时提供快速的查找、插入和删除操作。

二、插入操作实现

代码实现

# 定义树的节点
class BiTreeNode:
    def __init__(self, data):
        self.data = data
        self.lchild = None
        self.rchild = None
        self.parent = None


class BST:
    def __init__(self):  # 初始化二叉搜索树
        self.root = None

    def insert(self, node, val):  # 递归定义插入
        if not node:
            node = BiTreeNode(val)  # 如果是空树,那么直接创建新的节点插入
        elif val < node.data:  # 当插入的值小于根节点,就向左子树插入
            node.lchild = self.insert(node.lchild, val)  # 调用递归函数实现插入节点
            node.lchild.parent = node   # 并与父节点链接起来

        elif val > node.data: # 当插入的值大于根节点,就向右子树插入
            node.rchild = self.insert(node.rchild, val)  # 调用递归函数实现插入节点
            node.rchild.parent = node  # 并与父节点链接起来
        return node

    def insert_no_rec(self, val):  # 非递归定义插入  在下面详细解释
        p = self.root
        if not p:   # 空树
            self.root = BiTreeNode(val)  # 空树时直接新建节点插入即可
            return
        while True:
            if val < p.data:
                if p.lchild:  # 左孩子存在
                    p = p.lchild
                else:   # 左孩子不存在时直接创建节点插入
                    p.lchild = BiTreeNode(val)
                    p.lchild.parent = p
            elif val > p.data:
                if p.rchild:  # 右孩子存在
                    p = p.rchild
                else:  # 右孩子不存在时直接创建节点插入
                    p.rchild = BiTreeNode(val)
                    p.rchild.parent = p
                    return
            else:
                return


非递归插入详细过程 

使用非递归函数插入数据详细过程

1、随便定义一颗二叉搜索树(非空),将val = 12 插入到树中 。通过循环比较来实现数值的插入。

先将定义的 p 指针指向根节点,然后开始 val 与 根节点数值的比较。

2、 根据图中数值可知, val = 12 < p.data = 17,且 p点的左孩子 (p.lchild)存在,那么 p 指针向下移动,只执行 if val < p.data: 这块代码,变为如下图所示。

 while True:
            if val < p.data:
                if p.lchild:
                    p = p.lchild
                else:
                    p.lchild = BiTreeNode(val)
                    p.lchild.parent = p

 

 3.此时, val = 12 < p.data = 13,且 p点的左孩子 (p.lchild)存在,执行 p = p.lchild 语句,那么 p 指针向下移动,变为如下图所示。

4.此时, val = 12 > p.data = 7, 那么他要往右子树进行插入,且p.data 的右孩子不存在,就直接创建新的节点进行插入即可。

 elif val > p.data:
                if p.rchild:  # 右孩子存在
                    p = p.rchild
                else:  # 右孩子不存在时直接创建节点插入
                    p.rchild = BiTreeNode(val)
                    p.rchild.parent = p
                    return

最后插入结果为:

测试结果

对定义的函数进行测试,分别以先序,中序,后序输出。中序遍历都是从小到大输出,可以用作一种排序。

import random
class BiTreeNode:
    def __init__(self, data):
        self.data = data
        self.lchild = None
        self.rchild = None
        self.parent = None


class BST:
    def __init__(self, li=None):
        self.root = None
        if li:
            for val in li:
                self.insert_no_rec(val)

    def insert(self, node, val):  # 递归定义插入
        if not node:
            node = BiTreeNode(val)
        elif val < node.data:
            node.lchild = self.insert(node.lchild, val)
            node.lchild.parent = node
        elif val > node.data:
            node.rchild = self.insert(node.rchild, val)
            node.rchild.parent = node
        return node

    def insert_no_rec(self, val):
        p = self.root
        if not p:   # 空树
            self.root = BiTreeNode(val)
            return
        while True:
            if val < p.data:
                if p.lchild:
                    p = p.lchild
                else:
                    p.lchild = BiTreeNode(val)
                    p.lchild.parent = p
            elif val > p.data:
                if p.rchild:
                    p = p.rchild
                else:
                    p.rchild = BiTreeNode(val)
                    p.rchild.parent = p
                    return
            else:
                return

    def pre_order(self, root):
        if root:
            print(root.data, end=",")
            self.pre_order(root.lchild)
            self.pre_order(root.rchild)

    def in_order(self, root):
        if root:
            self.in_order(root.lchild)
            print(root.data, end=",")
            self.in_order(root.rchild)

    def post_order(self, root):
        if root:
            self.post_order(root.lchild)
            self.post_order(root.rchild)
            print(root.data, end=",")


li = list(range(0, 10))
random.shuffle(li)

tree = BST(li)
tree.pre_order(tree.root)  # 先序
print(" ")
tree.in_order(tree.root)   # 中序
print(" ")
tree.post_order(tree.root) # 后序

 输出结果

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于51单片机的定时器时钟设计[proteus仿真]

基于51单片机的定时器时钟设计[proteus仿真] 时钟设计检测系统这个题目算是课程设计和毕业设计中常见的题目了&#xff0c;本期是一个基于51单片机的定时器时钟设计 需要的源文件和程序的小伙伴可以关注公众号【阿目分享嵌入式】&#xff0c;赞赏任意文章 2&#xffe5;&…

【MySql学习之路】window环境下MySql安装和安装过程中出现的问题

environment:windows software:mysql 本文主要分享mysql关系型数据库在干净的环境下,第一次安装以及在安装过程中出现的常见问题和解决方法。目前官网给出的安装包有两种格式,一个是msi格式,一个是zip格式的。很多人下了zip格式的解压发现没有setup.exe,面对一堆文件无从…

【面试题】-02

素数之积 题目描述 RSA加密算法在网络安全世界中无处不在&#xff0c;它利用了极大整数因数分解的困难度&#xff0c;数据越大&#xff0c;安全系数越高&#xff0c;给定一个32位正整数&#xff0c;请对其进行因数分解&#xff0c;找出是哪两个素数的乘积。 输入描述 一个正整…

ORACLE Linux(OEL) - Primavera P6EPPM 安装及分享

引言 继上一期发布的CentOS版环境发布之后&#xff0c;近日我制作了基于ORACLE Linux的P6虚拟机环境&#xff0c;同样里面包含了全套P6 最新版应用服务 此虚拟机仅用于演示、培训和测试目的。如您在生产环境中使用此虚拟机&#xff0c;请先与Oracle Primavera销售代表取得联系…

[C/C++]string类常用接口介绍及模拟实现string类

一&#xff1a;Cstring类的由来 在C语言中&#xff0c;字符串是以\0结尾的一些字符的集合&#xff0c;为了操作方便&#xff0c;C标准库中提供了一些str系列的库函数&#xff0c;但是这些库函数与字符串是分离开的&#xff0c;不太符合OOP的思想&#xff0c;而且底层空间需要用…

动态规划|【路径问题】|174.地下城游戏

题目 174. 地下城游戏 恶魔们抓住了公主并将她关在了地下城 dungeon 的 右下角 。地下城是由 m x n 个房间组成的二维网格。我们英勇的骑士最初被安置在 左上角 的房间里&#xff0c;他必须穿过地下城并通过对抗恶魔来拯救公主。 骑士的初始健康点数为一个正整数。如果他的健…

数字化转型导师坚鹏:科技金融政策、案例及营销创新

科技金融政策、案例及营销创新 课程背景&#xff1a; 很多银行存在以下问题&#xff1a; 不清楚科技金融有哪些利好的政策&#xff1f; 不知道科技金融有哪些成功的案例&#xff1f; 不知道科技金融如何进行营销创新&#xff1f; 课程特色&#xff1a; 以案例的方式解…

复制表

目录 复制表 将部门 30 的所有员工信息保存在 emp30 表中 将复杂查询结果创建为表 只将 emp 表的结构复制为 empnull 表 从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 复制表 严格来说&#xff0c;复制表不是复制操作&am…

[QT]自定义的QtabWidget

需求 最近有一个需求就是一个QTabWidget要求有四个tab页在左侧用于显示主页面&#xff0c;在右侧有一个关于按钮&#xff0c;点击后用于弹出窗口显示一些程序相关信息。主要是怎么实现右侧按钮 相关代码 #ifndef MYTABWIDGET_H #define MYTABWIDGET_H#include <QWidget&g…

UDP通信发送和接收 || UDP实现全双工通信

recvfrom ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen); 功能: 从套接字中接收数据 参数: sockfd:套接字文件描述符 buf:存放数据空间首地址 …

康奈尔开源近10万份审稿意见,未来论文发表或将由AI定夺

大语言模型&#xff08;LLMs&#xff09;的进步为自动化论文评审开辟了新途径&#xff0c;这些模型在学术反馈领域展现出巨大潜力。自动化评审的核心优势在于其能够精准指出论文草稿的不足之处&#xff0c;助力作者优化研究。尽管已有丰富的同行评审数据&#xff0c;但现有自动…

利用websocket +定时器简易的实现一个网络聊天室

其实原理非常简单,就是客户端用户通过websoket来连接websocket服务端。然后服务端,收集每个用户发出的消息, 进而将每条用户的消息通过广播的形式推送到每个连接到服务端的客户端。从而实现用户的实时聊天。 // TODO : 我主要是讲一下实现思路。并未完善其功能。 1.后端 依赖 …

云原生(一)、linux快速上手

Linux是一种开源的Unix-like操作系统内核。它是由Linus Torvalds于1991年首次发布&#xff0c;其后经过全球的自由软件社区的持续开发和改进。Linux内核是操作系统的核心部分&#xff0c;但通常与GNU项目合作&#xff0c;以形成完整的操作系统&#xff0c;被称为Linux发行版&am…

每日OJ题_牛客WY28 跳石板(动态规划)

目录 牛客WY28 跳石板 解析代码 牛客WY28 跳石板 跳石板_牛客题霸_牛客网 解析代码 #include <iostream> #include <vector> #include <climits> #include <cmath> using namespace std;void get_div_num(int n, vector<int>& arr) {for…

基于java+springboot+vue实现的农产品智慧物流系统(文末源码+Lw)23-239

课题意义 现如今&#xff0c;信息种类变得越来越多&#xff0c;信息的容量也变得越来越大&#xff0c;这就是信息时代的标志。近些年&#xff0c;计算机科学发展得也越来越快&#xff0c;而且软件开发技术也越来越成熟&#xff0c;因此&#xff0c;在生活中的各个领域&#x…

WEBUI中的完美像素模式(Pixel Perfect)到底是什么意思

在webui的controlnet中&#xff0c;有个选项&#xff0c;叫做“完美像素模式”&#xff0c;英文为“pixel perfect mode”&#xff0c;有很多朋友在使用的时候不知道这个神奇的选项是否应该勾选上&#xff0c;所以有时候排查问题的时候&#xff0c;会反复的选择和去掉勾选&…

机器学习的基础学习笔记

黑马的学习视频 大家常说的人工智能、机器学习、深度学习其实是包含关系&#xff0c;深度学习是机器学习的一种特殊方法&#xff0c;而机器学习又是人工智能的一个子领域。 其中机器学习是使计算机系统能够通过学习经验和数据来改进性能。机器学习算法能够从数据中发现模式&am…

Igraph入门指南 5

2、graph_from系列&#xff0c;将其他R数据结构转换成图 2-1 邻接矩阵转图&#xff1a;graph_from_adjacency_matrix 可以接受Matrix包创建的稀疏矩阵作为参数 邻接矩阵中行的顺序被保留&#xff0c;并作为图中顶点的顺序。 本函数几个重要的参数&#xff1a; weighted&am…

美团 Java 开发笔试热经

Voiceover&#xff1a; 见者有缘&#xff0c;缘来好运。欢迎大家来到我的博客【CS_GUIDER】&#xff1a;&#xff08;建议收藏至浏览器书签&#xff09; https://wlei224.gitee.io &#xff08;建议访问这个&#xff0c;速度极快&#xff09; https://wl2o2o.github.io &#x…

Kafka 面试题及答案整理,最新面试题

Kafka中的Producer API是如何工作的&#xff1f; Kafka中的Producer API允许应用程序发布一流的数据到一个或多个Kafka主题。它的工作原理包括&#xff1a; 1、创建Producer实例&#xff1a; 通过配置Producer的各种属性&#xff08;如服务器地址、序列化方式等&#xff09;来…