C : DS二叉排序树之删除(详细思路解答)

news2024/9/29 23:22:36

Description

给出一个数据序列,建立二叉排序树,并实现删除功能

对二叉排序树进行中序遍历,可以得到有序的数据序列

Input

第一行输入t,表示有t个数据序列

第二行输入n,表示首个序列包含n个数据

第三行输入n个数据,都是自然数且互不相同,数据之间用空格隔开

第四行输入m,表示要删除m个数据

从第五行起,输入m行,每行一个要删除的数据,都是自然数

以此类推输入下一个示例

Output

第一行输出有序的数据序列,对二叉排序树进行中序遍历可以得到

从第二行起,输出删除第m个数据后的有序序列,输出m行

以此类推输出下一个示例的结果

Sample

Hint

当删除数据不在序列中,那么删除操作等于不执行,所以输出序列不变化

分析:删除的节点有三种情况。

  1. 叶子节点,即没有左子树和右子树

  2. 只有右子树或者只有左子树

  3. 同时有左右子树

思路:

        创建deleteNode方法,deleteNode(BinaryTreeNode*& t, int deleteNumber),传入参数为根节点以及删除的值。

 值相等之后进行判断

第一个判断:

左子树为空(包含叶子节点的情况,左右子树同时为空,右子树为NULL,temp会保存NULL,最后t被替换成NULL,相当于删除了叶子节点)

第二个判断:

右子树为空,左子树不为空。操作同上

 第三个判断:

左右子树都不为空。先找到右子树上最小节点,于是用函数BinaryTreeNode* findMinNode(BinaryTreeNode* t)进行寻找,进入右子树之后,当前节点不存在左子树时即为最小值。t为当前要删除的节点,用右子树上最小节点值替换当前节点值。替换值完成后进入右子树,重新调用deleteNode删除掉右子树最小节点即完成替换。

 例如:

最关键的是要对二叉排序树的性质要熟悉,左子树上所有的值都小于根节点,右子树上所有的值都大于根节点。

AC代码:

#include <iostream>
using namespace std;

struct BinaryTreeNode {
    int data;
    BinaryTreeNode* left;
    BinaryTreeNode* right;
    BinaryTreeNode() {
        data = 0;
        left = NULL;
        right = NULL;
    }
};

class BinaryTree {
public:
    BinaryTreeNode* root;

    BinaryTree() {
        root = nullptr;
    }

    ~BinaryTree() {
        destroyTree(root);
    }

    void init(BinaryTreeNode*& t, int data) {
        if (t) {
            if (data > t->data && t->right) {
                init(t->right, data);
            }
            else if (data < t->data && t->left) {
                init(t->left, data);
            }
            else if (data == t->data) {
                return;
            }
            if (data > t->data && t->right == NULL) {
                BinaryTreeNode* newNode = new BinaryTreeNode;
                newNode->data = data;
                t->right = newNode;
            }
            else if (data < t->data && t->left == NULL) {
                BinaryTreeNode* newNode = new BinaryTreeNode;
                newNode->data = data;
                t->left = newNode;
            }
        }
        else {
            t = new BinaryTreeNode;
            t->data = data;
        }
    }

    void midTree(BinaryTreeNode* t) {
        if (t) {
            midTree(t->left);
            cout << t->data << " ";
            midTree(t->right);
        }
    }

    void deleteNode(BinaryTreeNode*& t, int deleteNumber) {
        if (t == nullptr) {
            return;
        }
        //通过删除值与当前节点值进行比较,进行递归处理,直到值相等。
        if (deleteNumber > t->data) {
            deleteNode(t->right, deleteNumber);
        }
        else if (deleteNumber < t->data) {
            deleteNode(t->left, deleteNumber);
        }
        else {
            if (t->left == nullptr) {//左子树为空(包含叶子节点的情况,左右子树同时为空,右子树为NULL,temp会保存NULL,最后t被替换成NULL,相当于删除了叶子节点)
                BinaryTreeNode* temp = t->right;//临时节点保存右子树
                delete t;//删除当前节点
                t = temp;//用右子树替换当前节点
            }
            else if (t->right == nullptr) {//右子树为空,左子树不为空。操作同上
                BinaryTreeNode* temp = t->left;
                delete t;
                t = temp;
            }
            else {//左右子树都不为空。
                //找到右子树上最小节点
                BinaryTreeNode* minNode = findMinNode(t->right);
                //t为当前要删除的节点,用右子树上最小节点值替换当前节点值。
                t->data = minNode->data;
                deleteNode(t->right, minNode->data);//然后进入右子树,删除掉右子树最小节点即完成替换。
            }
        }
    }

    BinaryTreeNode* findMinNode(BinaryTreeNode* t) {
        while (t->left != nullptr) {
            t = t->left;
        }
        return t;
    }

    void destroyTree(BinaryTreeNode* t) {
        if (t) {
            destroyTree(t->left);
            destroyTree(t->right);
            delete t;
        }
    }
};

int main() {
    int t;
    cin >> t;

    while (t--) {
        int n;
        cin >> n;
        BinaryTree p;
        while (n--) {
            int data;
            cin >> data;
            p.init(p.root, data);
        }
        p.midTree(p.root);
        cout << endl;

        int deleteTimes;
        cin >> deleteTimes;
        while (deleteTimes--) {
            int deleteNum;
            cin >> deleteNum;
            p.deleteNode(p.root, deleteNum);
            p.midTree(p.root);
            cout << endl;
        }
    }
}

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

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

相关文章

《PySpark大数据分析实战》-15.云服务模式Databricks介绍创建集群

&#x1f4cb; 博主简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是wux_labs。&#x1f61c; 热衷于各种主流技术&#xff0c;热爱数据科学、机器学习、云计算、人工智能。 通过了TiDB数据库专员&#xff08;PCTA&#xff09;、TiDB数据库专家&#xff08;PCTP…

FastAPI访问/docs接口文档显示空白、js/css无法加载

如图&#xff1a; 原因是FastAPI的接口文档默认使用https://cdn.jsdelivr.net/npm/swagger-ui-dist5.9.0/swagger-ui.css 和https://cdn.jsdelivr.net/npm/swagger-ui-dist5.9.0/swagger-ui-bundle.js 来渲染页面&#xff0c;而这两个URL是外网的CDN&#xff0c;在国内响应超…

云仓酒庄的品牌雷盛红酒LEESON分享红酒存放几年质量最佳?

云仓酒庄的品牌雷盛红酒LEESON分享对于酒的看法&#xff0c;有人认为“酒是陈的香”&#xff0c;酒越老越好。不过对于葡萄酒来说&#xff0c;这种说法不完全对&#xff0c;如果一款葡萄酒等待的时间太久&#xff0c;未必是件好事。对待葡萄酒也要把握一个“度”&#xff0c;既…

STM32启动过程

STM32启动模式&#xff08;自举模式&#xff09; M3/3/7等内核&#xff0c;复位后做的第一件事&#xff1a; 从地址0x0000 0000处取出栈指针MSP的初始值&#xff0c;该值就是栈顶地址。从地址0x0000 0004处取出程序计数器指针PC的初始值&#xff0c;该值是复位向量。 芯片厂商…

【BIG_FG_CSDN】*VMware17pro*Linux*Redhit6网络管理(个人向——学习笔记)

物理机中的网络 查看物理网络的方法 “网络连接”—>单点选中网络的选项-->菜单栏中“查看此连接状态”-->“详细信息” “网络连接”中的VM网卡 在主机上对应的有VMware Network Adapter VMnet1和VMware Network Adapter VMnet8两块虚拟网卡&#xff0c;它们分别…

Python四种配色方案,适合科研的配色

1、Plasma&#xff08;等高线图颜色&#xff09;2、Inferno&#xff08;黑热图颜色&#xff09;3、Cividis&#xff08;较好的配色方案&#xff0c;适用于色盲&#xff09;4、Viridis&#xff08;绿色主导的配色方案&#xff09; 下面这四种配色是不需要指定的&#xff0c;Pyth…

个微和企微,哪个做私域流量的优势更大?

个人微信和企业微信是目前最为常用的私域经营平台&#xff0c;那在功能和使用上都有哪些区别&#xff1a; 1、开通对象不同&#xff1a; 个人微信是个人用户&#xff0c;个人就可以申请开通使用&#xff1b; 企业微信则要由企业在官方网站申请开通&#xff0c;并完成实名认证…

泰坦陨落2找不到msvcr120文件的修复方法,分享多种解决方法

在玩泰坦陨落2这款游戏时&#xff0c;有些玩家可能会遇到找不到msvcr120.dll文件的问题。这个问题可能是由于游戏缺少必要的运行库导致的。下面我将分享一些解决这个问题的方法&#xff0c;希望对大家有所帮助。 一、问题分析 msvcr120.dll是Microsoft Visual C Redistributab…

C语言进阶第十一节 --------程序环境和预处理(包含宏的解释)

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…

一招教你如何绕过OpenAI API key创建时需要手机号验证

一招教你如何绕过OpenAI API key创建时需要手机号验证 虽然现在 ChatGPT 注册门槛极大地降低。但是&#xff0c;如果你是开发者或者需要第三方应用接入ChatGPT&#xff0c;此时就需要获取一个 API key&#xff0c;然而你可能会发现在你在创建 key 的过程中需要进行手机号验证。…

可控硅(晶闸管)原理图及可控硅工作原理分析

可控硅(晶闸管)原理图 可控硅T在工作过程中&#xff0c;它的阳极A和阴极K与电源和负载连接&#xff0c;组成可控硅的主电路&#xff0c;可控硅的门极G和阴极K与控制可控硅的装置连接&#xff0c;组成可控硅的控制电路。 从可控硅的内部分析工作过程&#xff1a; 可控硅是四层…

校园转转二手市场源码+Java二手交易市场整站源码

源码介绍 校园转转二手市场源码分享&#xff0c;Java写的应用&#xff0c;mybatis-plus 和 Hibernate随心用 后台地址&#xff1a;/home/index/index 账号密码&#xff1a;admin/123456 前台地址&#xff1a;/system/login

企业微信自动登录自定义系统

方法一&#xff1a;企业微信构造OAuth2链接跳转登录到自定义系统 企业微信自定义应用配置 构造网页授权链接 如果企业需要在打开的网页里面携带用户的身份信息&#xff0c;第一步需要构造如下的链接来获取code参数&#xff1a; https://open.weixin.qq.com/connect/oauth2/…

重新配置torch1.8 cuda11.1 torchtext0.9.0虚拟Pytorch开发环境

这里写目录标题 起因发现选择安装cuda 11.1核对下自己的显卡是否支持下载该版本的CUDACUDA下载地址CUDA安装过程在anaconda中创建一个虚拟环境1.以下是环境的配置过程2.查看虚拟环境列表3.激活虚拟环境4.输入这句代码&#xff0c;没想到就可以直接安装torch和torchtext了[网站在…

计算机基础,以及实施运维工程师介绍

目录 一.实施&#xff0c;运维工程师介绍 1.什么是实施工程师&#xff1f; 实施工程师职责 2.什么是运维工程师&#xff1f; 运维工程师职责 3.实施运维需要的技术 数据库 操作系统 网络 服务器 软件 硬件 网络 二.计算机介绍 CPU 存储器 io 总线 主板 三.操…

【lesson18】MySQL内置函数(1)日期函数和字符串函数

文章目录 日期函数函数使用具体使用案例建表插入数据建表插入数据 字符串函数函数使用具体使用案例建表插入数据测试 日期函数 函数使用 获得年月日&#xff1a; 获得时分秒&#xff1a; 获得时间戳&#xff1a; 获得现在的时间&#xff1a; 在日期的基础上加日期&#xf…

JavaWeb 学生信息管理系统

介绍 ServletMysqlJdbcjQuery 实现学生信息管理系统 学生 班级 教师 系统设置 登陆 软件架构 软件架构说明 基于ServletMysqlJdbcjQuery 实现学生信息的增删改查功能 文件目录声明 src/dao 数据库的增删改查功能src/filter 网页的过滤拦截功能src/model 登陆的实体对象信息…

深度学习 Day19——P8YOLOv5-C3模块实现

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 文章目录 前言1 我的环境2 代码实现与执行结果2.1 前期准备2.1.1 引入库2.1.2 设置GPU&#xff08;如果设备上支持GPU就使用GPU,否则使用C…

[BJDCTF2020]Mark loves cat1

提示 -信息收集.git泄露php代码审计 拿到题先做信息收集 这里用dirsearch扫了下目录 ###如果没有dirsearch我在之前的这篇博客有写dirsearch的安装环境以及地址还有怎么扫buuctf里的题 [GXYCTF2019]禁止套娃1-CSDN博客 从扫描结果来看这里存在git泄露 这里使用githack拉下来git…

Java并发(二十)----synchronized原理进阶

1、小故事 故事角色 老王 - JVM 小南 - 线程 小女 - 线程 房间 - 对象 房间门上 - 防盗锁 - Monitor-重量级锁 房间门上 - 小南书包 - 轻量级锁 房间门上 - 刻上小南大名 - 偏向锁 -对象专属于某个线程使用 批量重刻名 - 一个类的偏向锁撤销到达 20 阈值 -批量重偏向 …