二叉搜索树(BST)的基本操作

2023-11-20

二叉搜索树(BST)的创建、增加、删除、查找。需要注意:BST的左子树必小于根,右子树必大于根,所以不存在值相同的结点。

#include<bits/stdc++.h>
using namespace std;
/*
    BST基本操作:
        00)递归插入 
        01)非递归插入
        02)调用insert()创建树 
        03)直接创建树 
        04)查找
        05)删除(用右侧最小值替换被删除的结点)
        06)删除(把左子树插入右子树) 
*/

/*
    BST:
        1)是一棵空树
        2)具有下列性质的二叉树: 
            若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 
            若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 
            它的左、右子树也分别为二叉排序树。 
    特点:
        中序周游为递增序列 
*/

//BST结点结构 
typedef class Node
{
    public:
        int val;
        Node *left;
        Node *right;
        Node(){ left = right = NULL; }
        Node(int tval){ val = tval; left = right = NULL; }
} *BST;

//递归前序周游:
void print_preOrder_recursion(BST root)
{
    if(root != NULL)
    {
        print_preOrder_recursion(root->left);
        cout << root->val;
        print_preOrder_recursion(root->right);
    }
}

/*
    递归插入(此结点数据已存在时插入失败,不存在时插入成功):
        遇到空结点时把数据插入; 
        遇到非空结点时若新数据大于当前结点数据,右下降;小于当前结点时,左下降 
*/ 
bool insert_recursion(BST &root, Node* data)
{
    if(root == NULL)
    {
        root = data;
        return true;
    }
    else{
        if(root->val < data->val)
            return insert_recursion(root->right, data);
        else if(root->val > data->val)
            return insert_recursion(root->left, data);
        return false;
    }
}
/*
    非递归插入(此结点数据已存在时插入失败,不存在时插入成功):
        遇到非空结点时若新数据大于当前结点数据,右下降;小于当前结点时,左下降
        遇到空结点时把数据插入,需要保留当前父结点,否则数据插不进去。 
*/ 
bool insert_noRecursion(BST root, Node* data)
{
    BST pointer = root, last;
    int flag;
    while(pointer != NULL)
    {
        last = pointer;
        if(pointer->val < data->val)
        {
            flag = 1; 
            pointer = pointer->right;
        }else if(pointer->val > data->val){
            flag = -1;
            pointer = pointer->left;
        }else
            return false;
    }
    flag > 0 ? last->right = data : last->left = data;
    return true;
}


/*
    调用insert()创建BST
*/
BST createBST_indirect()
{
    int n, val;
    cin >> n;
    BST root = NULL;
    for(int i = 0; i < n; i++)
    {
        cin >> val;
        insert_recursion(root, new Node(val));
    }
    return root;
}

/*
    直接创建BST:
        需要保存当前指向结点的父亲结点 
*/
BST createBST_direct()
{
    int n, i, val, flag = 0;
    cin >> n;
    if(n <= 0)
        return NULL;
    cin >> val;
    BST root = new Node(val), pointer = NULL, last = NULL;
    for(i = 1; i < n; i++)
    {
        cin >> val;
        pointer = root;
        while(pointer != NULL)
        {
            last = pointer;
            if(pointer->val < val)
            {
                flag = 1;
                pointer = pointer->right;
            }else if(pointer->val > val){
                flag = -1;
                pointer = pointer->left;
            }else{              //此数据已存在时,跳过 
                flag = 0;
                break;
            }
        }
        if(flag == 0)
            continue;
        flag > 0 ? last->right = new Node(val) : last->left = new Node(val);
    }
    return root;
}

/*
    查找:
        周游一遍即可。 
*/
bool find(BST root, int val)
{
    if(root != NULL) 
    {
        if(root->val == val)
            return true;
        else if(val < root->val)
            return find(root->left, val);
        else
            return find(root->right, val);
    }
    return false;
}
/*
    删除(不改变总体结构):
        利用 BST中序周游非递减的性质寻找需要删除的结点
        用右侧最小结点覆盖被删除的结点,然后删除右侧最小结点 
*/
BST delData_noChangeStructure(BST root, int val)
{
    if(root == NULL)
        return NULL;
    if(root->val < val)
        root->right = delData_noChangeStructure(root->right, val);
    else if(root->val > val)
        root->left = delData_noChangeStructure(root->left, val);
    else{
        if(root->left == NULL || root->right == NULL)
            return root->left == NULL ? root->right : root->left;
        BST temp = root->right;
        while(temp->left != NULL)
            temp = temp->left;
        root->val = temp->val;
        root->right = delData_noChangeStructure(root->right, root->val);
        return root;
    }
}

/* 
    删除(改变总体结构):
        利用 BST中序周游非递减的性质寻找需要删除的结点
        然后把左子树结点根结点插入右子树 
*/
BST delData_changeStructure(BST root, int val)
{
    if(root == NULL)
        return NULL;
    if(root->val < val)
        root->right = delData_noChangeStructure(root->right, val);
    else if(root->val > val)
        root->left = delData_noChangeStructure(root->left, val);
    else{
        if(root->left == NULL || root->right == NULL)
            return root->left == NULL ? root->right : root->left;
        insert_noRecursion(root->right, root->left); 
        root->left = NULL;
        root = delData_changeStructure(root, root->val);
        return root;
    }
}
int main()
{
    BST root = createBST_indirect();
    insert_recursion(root, new Node(4));
    print_preOrder_recursion(root);
    cout << endl;
    insert_recursion(root, new Node(9));
    print_preOrder_recursion(root);
    cout << endl;
    cout << find(root, 10) << "   " << find(root, 4) << endl; 
    BST del1 = delData_noChangeStructure(root, 2);
    print_preOrder_recursion(del1);
    cout << endl;
    BST del2 = delData_noChangeStructure(root, 3);
    print_preOrder_recursion(del1);
    return 0;
}
/*
    input:
        5
        2 4 1 3 0 
    BST:
            2
          1   4
        0    3 9
*/
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

二叉搜索树(BST)的基本操作 的相关文章

  • 变分模态分解(VMD)运算步骤及源码解读

    1 简述 VMD的目标是将实值输入信号 f f f分解为离散数量的子信号 模态 u k u k uk 我们先假设每个模态在一个中心频率
  • Axure谷歌Chrome浏览器插件安装教程

    1 引言 经常看到这样的问题 1 我用Axure做的原型怎么不能用谷歌浏览器查看 2 到哪里下载Axure谷歌浏览器插件 3 Axure谷歌浏览器插件下载下来怎么安装 其实这些问题百度一下都能找到答案 不过有些答案对于新手来说比较麻烦 就拿
  • c语言函数中调用的参数太多

    c语言函数中调用的参数太多问题 问题展示 问题分析 解决方法 问题展示 图中是我遇到的情况 问题分析 大家可以看到 在函数中 指针变量和后面的整数变量都成了灰色 解决方法 图中问题只需将中文逗号 改为英文逗号即可 一定要检查双引号或者逗号是
  • QT中使用Sqlite

    QT中使用Sqlite 首先要在 pro中引用sql 引用方法 新添加语句 QT sql 在原来的基础上追加 QT core gui sql 然后再widget h中添加对sql头文件的引用 include
  • idea connect timed out 解决方法

    使用IntelliJ IDEA 创建Spring Boot项目时 显示 connect timed out 解决方法 1 很多博客说将 https start spring io 改为 http start spring io 但是我这里不
  • 手动切换 Kinect 的驱动程序(for OpenNI 1.* & Microsoft Kinect SDK 1.7)

    微软最近推出了最新版的 Kinect SDK 能够实现实时的 Kinect Fusion 并提供了丰富的手势交互功能 对体感交互开发人员的吸引力越来越大 而 OpenNI 2 0 以上的版本也转为使用微软官方的 Kinect 驱动 也显示了
  • 移动端适配-01-百分比宽度

    1 图片可以在parent中使用 1 line heigh和text align使水平和竖直居中 2 在img标签中加vertical align middle 2 3 background size 1 两个参数 background s
  • Ubuntu18.04安装cuda10.1+cudnn8.0.5+pytorch1.8.1【亲测~】

    Ubuntu18 04安装cuda10 1 cudnn8 0 5 pytorch1 8 1 亲测 目录 第一步 Cuda10 1的安装 第二步 Cudnn8 05的安装 1 进入官网 https developer nvidia com r
  • [思维模式-15]:《复盘》-3- “行”篇 - 操作复盘- 个人复盘

    目录 前言 一 将军不是教出来的 而是打出来的 二 复盘是能力提升的有效方式 三 对什么进行个人复盘 1 新的事 2 重要的事 3 有价值的事 4 按照规范 惯例处置不太奏效的事件 未达预期的事 四 个人复盘的两种操作手法 1 自我简易复盘
  • cisco 小型园区与网络的构建及其应用

    一 实验目的 熟练构建小型区域网络 二 实验设备 Cisco 2811 路由器 6台 cisco 3650 交换机 6台 cisco 2960 交换机7台 pc机8台 服务器6台 数据线缆若干 三 实验拓扑 四 实验步骤
  • applicationContext.xml第一行无缘无故报错!!!

    eclipse的bug 在projects里clean一下 就好了 右键project的validate不管用
  • python实现OCR识别图片验证码

    用cv2模块读取和显示模块 导包cv2拓展模块 import cv2 先给窗体起名字 cv2 namedWindow ShowImage1 cv2 namedWindow ShowImage2 image1 cv2 imread img01

随机推荐

  • 04757信息系统开发与管理2011版考试大纲思维导图

    第一章 第二章 第三章 第四章 第五章 第六章 第七章 第八章 第九章 不考 思维导图下载地址 MindMaster绘制 链接 https pan baidu com s 1U BRcRyUgZ8QUqlDuOLy w pwd qwzt 提
  • 通过 raft 的 leader lease 来解决集群脑裂时的 stale read 问题

    通过 raft 的 leader lease 来解决集群脑裂时的 stale read 问题 问题 当 raft group 发生脑裂的情况下 老的 raft leader 可能在一段时间内并不知道新的 leader 已经被选举出来 这时候
  • C语言冒泡排序和选择排序

    一 冒泡排序法 假设从小到大排序 例一数组 int arr 2 1 34 5 arr 0 先跟相邻的arr 1 比较大小 如果比它大则交换两个数值位置 大的数值放在后面 然后比较arr 1 和arr 2 的大小 以此类推 直至第n 2个和第
  • MCDF实验——Lab0

    MCDF实验 一 MCDF功能描述 二 设计结构 三 接口描述 1 系统信号接口 2 通道从端接口 3 整形器接口 4 控制寄存器接口 四 接口时序 1 通道从端接口时序 2 整形器接口时序 3 控制寄存器接口时序 五 寄存器描述 1 地址
  • day4-Django的model

    目录 1 setting文件配置 2 理解models 3 model定义 4 常用字段类型 5 常用属性 6 数据库迁移 7 Meta类 1 setting文件配置 sqlite数据库 DATABASES default ENGINE d
  • AIGC潮水中,重新理解低代码

    如果将一句话生成应用形容成L4级的 无人驾驶 伙伴云的 AI搭建 则更像L2 级的 辅助驾驶 作者 斗斗 出品 产业家 2023年 AIGC下的低代码赛道 暗流涌动 对于 AI搭建 的搭建效果 尤其是在场景覆盖的广度上 连我自己也感觉比较意
  • Qt Creator创建C++(Day1)

    利用Qt Creator创建纯C 项目流程 1 如下图所示 按照序号选择即可 2 更改名字和选择保存路径 3 点击 下一步 4 直接点击 完成 注意事项 如果在控制台输出中文乱码修改过程如下 1 选中 工具 选项 2 将 UTF 8 改为
  • 语音活性检测器 webrtcvad

    目录 概述 安装 使用脚本 1 测试静音片段 2 清理静音片段 概述 WebRTC是一个免费 开放的框架 项目 使web浏览器通过简单的JavaScript api接口实现实时通信功能 WebRTC An open framework fo
  • 动态规划之多重背包模型

    前置知识 01背包问题 动态规划之01背包模型 如何何何的博客 CSDN博客 完全背包问题 动态规划之完全背包模型 如何何何的博客 CSDN博客 多重背包问题 给定一个有一定容量的背包 和 n 个物品 每个物品有 si 件 每个物品有其对应
  • taoCMS v3.0.2 任意文件上传漏洞(CVE-2022-23880)

    靶标介绍 taoCMS v3 0 2 文件管理处存在任意文件上传漏洞 攻击者可执行任意代码 漏洞复现 1 使用御剑扫描后台 或者直接输入 admin 就会跳转到登录界面 弱口令尝试 账号admin 密码tao 2 在文件管理处 新建文件为1
  • CVPR 2023

    点击下方卡片 关注 CVer 公众号 AI CV重磅干货 第一时间送达 点击进入 gt 计算机视觉和Transformer 交流群 作者 Oliiiver 源 知乎 编辑 CVer公众号 https zhuanlan zhihu com p
  • 使用TensorFlow Lite将深度学习模型部署到IOT系统

    使用TensorFlow Lite将深度学习模型部署到IOT系统 TensorFlow Lite简介 移动设备深度学习框架是部署在手机或者树莓派等小型移动设备上的深度学习框架 可以使用训练好的模型在手机等设备上完成推理任务 这一类框架的出现
  • yolov5--完全炼丹指南

    目录 前言 炼丹方法 收集数据集 划分数据集 yolov5模型训练 简单提升训练效果的措施 关于参数的说明 结语 前言 最近在做yolov5识别手势的项目 爬了很多坑 也排除了不少bug 记录一下 参考前人的经验 遇到写得好的文章我会推荐
  • 打印出1-10000之间的所有对称数(如121,1331,2442)。

    练习题 打印出1 10000之间的所有对称数 如121 1331 2442 自己写的代码 var isSym function num var str for var i 1 i lt 9 i 如果个位算 可去掉注释 str i str f
  • 干掉广告和钓鱼,这款神器绝了!

    大家好 我是良许 前几天 搜狐丢人丢大发了 自家的员工居然遭遇了钓鱼诈骗 据报道 某员工使用邮件时被意外钓鱼导致密码泄露 进而被冒充财务部盗发邮件 共有 24 名员工被骗取 4 万余元 要知道 搜狐可是国内最早的四大门户网站之一 同时也是国
  • 【9.19】正则表达式——sed、awk

    9 19 正则表达式 sed awk 9 4 9 5 sed 1 sed 匹配 2 sed打印具体行数 3 sed 替换功能 9 6 9 7 awk 1 awk 匹配 2 awk 数学运算表达式 3 两个字段比较大小 4 内置变量 OFS
  • Vue (三) 生命周期--钩子函数

    生命周期 Vue官网生命周期的描述 钩子函数 1 beforeCreate 创建Vue实例化之前所调用的函数 div h1 message h1 div
  • webpack高版本configuration.module has an unknown property ‘loaders‘

    webpack更换高版本后报错 webpack cli Invalid configuration object Webpack has been initialized using a configuration object that
  • ffmpeg已支持解码avs2.0

    https ffmpeg org pipermail ffmpeg devel 2016 November 202446 html PS 目前应该还是个提交的patch 待审核
  • 二叉搜索树(BST)的基本操作

    二叉搜索树 BST 的创建 增加 删除 查找 需要注意 BST的左子树必小于根 右子树必大于根 所以不存在值相同的结点 include