【数据结构与算法】二叉树

二叉树

  • 一.二叉树的结构
  • 二.二叉树的插入
    • 1.根的插入
    • 2.其他的插入
  • 三.二叉树的删除
    • 1.找到删除节点
    • 2.删除节点的子节点只有一个或没有
    • 3.删除节点的子节点有两个
  • 四.完整代码

一.二叉树的结构

树的形式多种多样,但是我们最常用的还是二叉树.在二叉树中最长用的又数二叉搜索树.
在这里插入图片描述
这就是一个二叉搜索树,可以看到每个节点的左边都小于右边.

对于二叉树的实现,我们采用的链式结构

在这里插入图片描述
在这里插入图片描述
就是两个指针一个数据,跟双向链表差不多,但是两个节点之间不是双向连接.
左右指针都是指向的新的节点.

二.二叉树的插入

插入就要符合我们的规律,左边的的小于右边的.

1.根的插入

在这里插入图片描述
对要插入的节点,我们做防御性编程,同时对左右孩子设置为空.
在这里插入图片描述
当姚插入的是根节点是空,我们直接将新姚插入的节点设置为根节点.
如果不为空,先用变量进行保存,因为我们要进行遍历.

2.其他的插入

姚找到插入的位置就需姚遍历,找到要插入节点的父节点.
在这里插入图片描述
如果要插入的数据小于根节点的数据,就往左边遍历,否则右边遍历,直到tmp为空,那么parent就是要删除节点的父节点.

找到位置后然后进行插入:
在这里插入图片描述
如果要插入的数据小于父节点的数据,就插入在左边,否则右边.

三.二叉树的删除

对于删除稍稍有点复杂,有好几种情况如下.

1.找到删除节点

还是需要遍历到要删除节点:
在这里插入图片描述
如果当前节点不为空,同时当前节点的数据不是我们要删除的数据,那么我们一直遍历.
如果要删除节点的数据小于当前节点就往左边遍历,否则右边.
在这里插入图片描述
如果最后遍历为空,那么就是没有找到姚删除的节点.

2.删除节点的子节点只有一个或没有

当找到要删除的节点后,如果要删除节点的左边为空,就将姚删除节点的右边节点连接到要删除节点的位置,同理姚删除节点的右边为空的时候,就将要删除节点的左边连接到要删除的节点.
如果姚删除节点没有左右子节点了,那么连接的就是空.

在这里插入图片描述

在这里插入图片描述

如果父节点为空,那么就是要删除根节点,直接将刚刚子节点作为根节点.
在这里插入图片描述
要删除节点的父节点直接将原来的孩子改变成为原来孩子的孩子.

3.删除节点的子节点有两个

在这里插入图片描述
我们这里选择找右子树的最小值,先将要删除节点的右孩子找到,然后根据二叉搜索树的性质,我们需要一直找其左子节点,能够找到最小的值.
找到最小的值后,然后将其赋值给要删除的节点.

在这里插入图片描述

然后对刚刚找到的最小值位置进行删除,其父节点等于其要删除节点的孩子节点.
在这里插入图片描述

四.完整代码

#include <stdio.h>
#include <iostream>
#include <assert.h>typedef int ElemType;
#define isLess(a,b)(a<b)
#define isEqual(a,b)(a==b)typedef struct _Bnode
{ElemType data;struct _Bnode* lchild, * rchild;
}Bnode,Btree;bool InsertBtree(Btree** root, Bnode* node)
{Bnode* tmp = NULL;Bnode* parent = NULL;if (!node) {return false;}else{node->lchild = NULL;node->rchild = NULL;}if (*root){tmp = *root;}else{*root = node;return true;}while (tmp!=NULL){parent = tmp;printf("父节点: %d\n", parent->data);if (isLess(node->data, tmp->data)){tmp = tmp->lchild;}else{tmp = tmp->rchild;}}if (isLess(node->data, parent->data)){parent->lchild = node;}else{parent->rchild = node;}return true;
}int findMax(Btree* root)
{assert(root != NULL);/*if (root->rchild == NULL){return root->data;}return findMax(root->rchild);*/while (root->rchild){root = root->rchild;}return root->data;
}Btree* DeleteNode(Btree* root, int key)
{if (root == NULL)return NULL;if (root->data > key){root->lchild = DeleteNode(root->lchild, key);return root;}if (root->data < key){root->rchild = DeleteNode(root->rchild, key);return root;}if (root->lchild == NULL && root->rchild == NULL)return NULL;if (root->lchild == NULL && root->rchild != NULL)return root->rchild;if (root->lchild != NULL && root->rchild == NULL)return root->lchild;int val = findMax(root->lchild);root->data = val;root->lchild = DeleteNode(root->lchild, val);return root;
}Btree* DeleteNodeNonRecursive(Btree* root, int key) {Btree* current = root;Btree* parent = NULL;while (current != NULL && current->data != key) {parent = current;if (key < current->data) {current = current->lchild;}else {current = current->rchild;}}if (current == NULL) {return root; // 未找到节点}// 处理叶子节点或只有一个子节点的情况if (current->lchild == NULL || current->rchild == NULL) {Btree* newCurrent;if (current->lchild == NULL) {newCurrent = current->rchild;}else {newCurrent = current->lchild;}if (parent == NULL) {root = newCurrent;}else if (parent->lchild == current) {parent->lchild = newCurrent;}else {parent->rchild = newCurrent;}}else { // 有两个子节点的情况Btree* successor = current->rchild;Btree* successorParent = current;while (successor->lchild != NULL) {successorParent = successor;successor = successor->lchild;}current->data = successor->data;if (successorParent->lchild == successor) {successorParent->lchild = successor->rchild;}else {successorParent->rchild = successor->rchild;}}return root;
}int main()
{int test[] = { 19,7,25,5,11,15,21,61 };Bnode* root = NULL, * node = NULL;for (int i = 0; i < sizeof(test) / sizeof(test[0]); i++){node = new Bnode;node->data = test[i];InsertBtree(&root, node);}DeleteNode(root, 5);system("pause");return 0;
}

当然也可以用递归函数来实现.

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

云原生的候选应用

前言&#xff0c;到底哪些应用适合云原生&#xff1f; 云原生应用适合于多种场景&#xff0c;‌包括高并发、‌高负载的Web应用、‌大数据处理、‌容器化应用程序、‌微服务架构、‌DevOps、‌智能物联网、‌云原生区块链应用以及大数据和机器学习。‌ 高并发、‌高负载的Web…

RuntimeError: device >= 0 device < num_gpus INTERNAL ASSERT FAILED

参考网址 https://discuss.pytorch.org/t/runtimeerror-device-0-device-num-gpus-internal-assert-failed/178118/1 今天运行GPU发现一个很特别的问题&#xff0c;就是 解决办法

Vue的事件处理、事件修饰符、键盘事件

目录 1. 事件处理基本使用2. 事件修饰符3. 键盘事件 1. 事件处理基本使用 使用v-on:xxx或xxx绑定事件&#xff0c;其中xxx是事件名&#xff0c;比如clickmethods中配置的函数&#xff0c;都是被Vue所管理的函数&#xff0c;this的指向是vm或组件实例对象 <!DOCTYPE html&g…

【路由器】RT-AC88U华硕配置DNS

公共dns ip 测试了下就119.29.29.29 为53毫秒,谷歌的8.8.8.8为55毫秒。阿里的竟然有112毫秒。阿里DNS:阿里巴巴集团提供的公共DNS服务器,其服务器分布广泛,响应速度较快。主要DNS地址:223.5.5.5、223.6.6.6。 百度DNS:百度提供的公共DNS服务器,也具有较快的响应速度。主…

【原创】springboot+mysql疫苗预约网设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…

uni-app中如何使用日期选择器

uni-app中如何使用日期选择器&#xff0c;分别实现日&#xff0c;月&#xff0c;年 日 <picker mode"date" fields"day">是日的内容</picker> 月 <picker mode"date" fields"month">日期选择器</picker> 年…

C++快速理解之封装

c 成员访问限定符&#xff1a;private、protected、public 1.是什么&#xff1f; 一种权限标记&#xff0c;就是你能不能使用该类中的成员 2.为什么要用&#xff1f; 一个对象&#xff0c;由很多数据&#xff08;成员变量&#xff09;很多函数&#xff08;成员函数&#xf…

STM32常见的下载方式有三种

经过对比&#xff0c;推荐使用 SWD下载&#xff0c;只需要一个仿真器&#xff08;如jLINK、ST LINK、 CMSIS DAP 等&#xff09;&#xff0c;比较方便。 不推荐使用串口下载&#xff08;速度慢、无法仿真和调试&#xff09;和 JTAG 下载&#xff08;占用 IO 多&#xff09;。

WPF参考做的TextBox圆角,并且水印文字操作

1.首先进行 转换器操作&#xff08;获取当前Textbox Text是否为空或者空格&#xff09; / // <summary>/// 非空验证转换器/// </summary>#region String IsNullOrEmptypublic class IsNullOrEmptyConverter : IValueConverter{public object Convert(object valu…

C++——模板进阶

小伙伴们大家好啊&#xff0c;停更了两个月深表歉意&#xff0c;作者调整好了状态&#xff0c;今后将继续为大家分享C的相关知识。 在前面的模板初阶中&#xff0c;我们介绍了模板的基本类型以及用法&#xff0c;包括函数模板和类模板&#xff0c;本文我们讲对模板进行更深入的…

ffmpeg -- 常用口令

文章目录 1.视频格式转换2.设置比特率3.设置帧率4.强制让输入视频帧率为1&#xff0c;输出视频帧率为245.长视频截短6.自动分割视频的bash脚本7.每一帧都保存成图片 1.视频格式转换 ffmpeg -i input.avi output.mp42.设置比特率 ffmpeg -i input.avi -b:v 64k -bufsize 64k o…

甄选范文“论负载均衡技术在Web系统中的应用”软考高级论文系统架构设计师论文

论文真题 负载均衡技术是提升Web系统性能的重要方法。利用负载均衡技术, 可将负载(工作任务) 进行平衡、分摊到多个操作单元上执行, 从而协同完成工作任务, 达到提升Web系统性能的目的。 请围绕“负载均衡技术在Web系统中的应用”论题, 依次从以下三个方面进行论述。 1.…

【ARM】ULINK Pro如何和SWD接口进行连接调试

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 解决ULINK Pro和JTAR接口进行连接问题。 2、 问题场景 因为ULINK Pro本身自带的接口是Cortex-M ETM Interface 20-pin Connector。所以无法和JTAR接口直接进行连接。 图2-1 3、软硬件环境 1&#xff09;、软件版…

【微信小程序实战教程】之微信小程序中的 JavaScript

微信小程序中的 JavaScript 微信小程序的业务逻辑都是通过JavaScript语言来实现的&#xff0c;本章我们将详细的讲解JavaScript的基本概念&#xff0c;以及在小程序中如何使用JavaScript语言。JavaScript是一种轻量的、解释型的、面向对象的头等函数语言&#xff0c;是一种动态…

vue 开发工具 Hbuilder 简介及应用

一、简介 HBuilderX 是一款流行的前端开发工具&#xff0c;由DCloud公司开发。它支持多种编程语言&#xff0c;如HTML、CSS、JavaScript、Vue、UniApp等&#xff0c;非常适合用来开发Web应用、移动端应用和跨平台应用。 官网地址&#xff1a;https://www.dcloud.io/hbuilderx.…

UE基础 —— 工具和编辑器

目录 Level Editor Static Mesh Editor Material Editor Blueprint Editor Physics Asset Editor Behavior Tree Editor Niagara Editor UMG UI Editor Font Editor Sequencer Editor Animation Editor Control Rig Editor Sound Cue Editor Media Editor nDisp…

SB3045LFCT-ASEMI无人机专用SB3045LFCT

编辑&#xff1a;ll SB3045LFCT-ASEMI无人机专用SB3045LFCT 型号&#xff1a;SB3045LFCT 品牌&#xff1a;ASEMI 封装&#xff1a;TO-220F 批号&#xff1a;最新 最大平均正向电流&#xff08;IF&#xff09;&#xff1a;30A 最大循环峰值反向电压&#xff08;VRRM&…

【IEEE独立出版】第四届计算机科学与区块链国际学术会议 (CCSB 2024)

第四届计算机科学与区块链国际学术会议 (CCSB 2024) 2024 4th International Conference on Computer Science and Blockchain 2024年9月6-8日 中国-深圳 老牌会议 | 涵盖计算机学科 | 往届均完成见刊、稳定检索 | 论文录用速度快 | 有ISBN号! *关于IEEE出版社 电气电子工…

Ubuntu23.10 安装kvm并使用nmtui创建桥接网络

1.实验准备 &#xff08;1&#xff09;使用Vmware安装Ubuntu23.10 2.实验步骤 &#xff08;1&#xff09;配置ssh &#xff08;2&#xff09;安装qemu &#xff08;3&#xff09;安装libvirt服务 &#xff08;4&#xff09;安装virtinst &#xff08;5&#xff09;启动libvir…

Android14音频进阶调试之命令播放mp3/aac非裸流音频(八十)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 新书发布:《Android系统多媒体进阶实战》🚀 优质专栏: Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏: 多媒体系统工程师系列【原创干货持续更…