树结构及其算法-二叉树节点的删除

news2024/11/26 13:24:24

目录

树结构及其算法-二叉树节点的删除

C++代码


树结构及其算法-二叉树节点的删除

二叉树节点的删除操作稍为复杂,可分为以下3种情况。

  1. 删除的节点为树叶,只要将其相连的父节点指向NULL即可。
  2. 删除的节点只有一棵子树。
  3. 删除的节点有两棵子树。要删除节点,方式有两种,虽然结果不同,但是都符合二叉树的特性。
  • 找出中序立即先行者(Inorder Immediate Predecessor),就是将要删除节点的左子树中的最大者向上提。简单来说,就是从该节点的左子树往右寻找,直到右指针为NULL,这个节点就是中序立即先行者。
  • 找出中序立即后继者(Inorder Immediate Successor),就是把要删除节点的右子树中的最小者向上提。简单来说,就是从该节点的右子树往左寻找,直到左指针为NULL,这个节点就是中序立即后继者。

C++代码

#include<iostream>
using namespace std;

struct TreeNode {
	int data;
	TreeNode* leftNode;
	TreeNode* rightNode;
	TreeNode(int tempData, TreeNode* tempLeftNode = nullptr, TreeNode* tempRightNode = nullptr) {
		this->data = tempData;
		this->leftNode = tempLeftNode;
		this->rightNode = tempRightNode;
	}
};

class Tree {
private:
	TreeNode* treeNode;
public:
	Tree() {
		treeNode = nullptr;
	}
	TreeNode* GetTreeNode() {
		return this->treeNode;
	}
	void AddNodeToTree(int* tempData, int tempSize) {
		for (int i = 0; i < tempSize; i++) {
			TreeNode* currentNode;
			TreeNode* newNode;
			int flag = 0;
			newNode = new TreeNode(tempData[i]);
			if (treeNode == nullptr)
				treeNode = newNode;
			else {
				currentNode = treeNode;
				while (!flag) {
					if (tempData[i] < currentNode->data) {
						if (currentNode->leftNode == nullptr) {
							currentNode->leftNode = newNode;
							flag = 1;
						}
						else
							currentNode = currentNode->leftNode;
					}
					else {
						if (currentNode->rightNode == nullptr) {
							currentNode->rightNode = newNode;
							flag = 1;
						}
						else
							currentNode = currentNode->rightNode;
					}
				}
			}
		}
	}
	void DeleteNodeToTree(TreeNode* tempTree, int tempData) {
		if (tempTree == nullptr)
			return;
		TreeNode* findNode = tempTree;
		TreeNode* pre = nullptr;
		while (findNode != nullptr) {
			if (findNode->data == tempData)
				break;
			else if (tempData < findNode->data) {
				pre = findNode;
				findNode = findNode->leftNode;
			}
			else {
				pre = findNode;
				findNode = findNode->rightNode;
			}
		}
		if (findNode == nullptr)
			return;

		if (findNode->leftNode == nullptr) {
			if (findNode == tempTree) {
				TreeNode* temp = findNode;
				findNode = findNode->rightNode;
				free(temp);
			}
			TreeNode* temp = findNode;
			(pre->data < findNode->data ? pre->rightNode : pre->leftNode) = findNode->rightNode;
			free(temp);
			temp = nullptr;
		}
		else if (findNode->rightNode == nullptr) {
			if (findNode == tempTree) {
				TreeNode* temp = findNode;
				findNode = findNode->leftNode;
				free(temp);
			}
			TreeNode* temp = findNode;
			(pre->data < findNode->data ? pre->rightNode : pre->leftNode) = findNode->leftNode;
			free(temp);
			temp = nullptr;
		}
		else {
			TreeNode* post = findNode;
			TreeNode* max = findNode->leftNode;
			while (max->rightNode != nullptr) {
				post = max;
				max = max->rightNode;
			}
			findNode->data = max->data;
			if (post == findNode)
				post->leftNode = max->leftNode;
			else
				post->rightNode = max->rightNode;
			free(max);
		}
	}
	void Inorder(TreeNode* tempTree) {
		if (tempTree != nullptr) {
			Inorder(tempTree->leftNode);
			cout << tempTree->data << " ";
			Inorder(tempTree->rightNode);
		}
	}
	TreeNode* Find(TreeNode* tree, int value) {
		while (true) {
			if (tree == nullptr)
				return nullptr;
			if (tree->data == value)
				return tree;
			else if (tree->data > value)
				tree = tree->leftNode;
			else
				tree = tree->rightNode;
		}
	}
};

int main() {
	int data[]{ 7,4,1,5,16,8,11,12,15,9,2 };
	cout << "原始数据:" << endl;
	for (int i = 0; i < 11; i++)
		cout << data[i] << " ";
	cout << endl;

	Tree* tree = new Tree;
	tree->AddNodeToTree(data, 11);

	cout << "中序遍历:" << endl;
	tree->Inorder(tree->GetTreeNode());
	cout << endl;

	cout << "请输入要删除的值:";
	int value;
	cin >> value;
	if ((tree->Find(tree->GetTreeNode(), value)) == nullptr)
		cout << "二叉树中没有此节点了" << endl;
	else {
		tree->DeleteNodeToTree(tree->GetTreeNode(), value);
		cout << "中序遍历:" << endl;
		tree->Inorder(tree->GetTreeNode());
		cout << endl;
	}

	return 0;
}

输出结果

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

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

相关文章

Mysql高级操作和六大约束

一.数据库高级操作 1.1.克隆表 &#xff08;1&#xff09;克隆表&#xff0c;将数据表的数据记录生成到新的表中 方法一&#xff1a; create table test01 like KY08; #通过LIKE方法&#xff0c;复制KY08表结构生成test01 表 insert into test01 select * from KY08; #此方法…

分布式事务(再深入)——分布式事务理论基础 Java分布式事务解决方案

前言 事务(TRANSACTION)是一个不可分割的逻辑单元&#xff0c;包含了一组数据库操作命令&#xff0c;并且把所有的命令作为一个整体向系统提交&#xff0c;要么都执行、要么都不执行。 事务作为系统中必须考虑的问题&#xff0c;无论是在单体项目还是在分布式项目中都需要进行…

HAL服务整编错误处理

HAL服务整编错误处理 1、HIDL HAL服务2、HIDL HAL服务集成1》manifest.xml 配置报错2》hidl服务未启动报错3》有rc启动文件&#xff0c;没有so库报错4》SELinux权限问题5》整编译还是没有集成 或 报错 1、HIDL HAL服务 请参考下面几篇&#xff1a; 简单HIDL HAL的实现 Android系…

Ubuntu18.04LTS上安装ROS melodic

目录 前言创建source.list安装curl通过curl获取PGP公钥更新系统软件包索引安装ROS激活ROS系统空间 前言 本文参考ROS官方wiki&#xff0c;描述在Ubuntu18.04LTS上安装ROS的过程。 创建source.list sudo sh -c echo "deb http://packages.ros.org/ros/ubuntu $(lsb_rele…

「更新」Macos屏幕录像工具:ScreenFlow

mac电脑屏幕截图工具哪个好&#xff1f;ScreenFlow是Mac上的一款优秀的屏幕录像软件&#xff0c;它不仅具有屏幕录制功能&#xff0c;还具有视频编辑功能。以下是对ScreenFlow的一些详细介绍&#xff1a; 首先&#xff0c;ScreenFlow可以捕获摄像机、麦克风和计算机音频&#…

一段奇葩的1024代码

入门教程、案例源码、学习资料、读者群 请访问&#xff1a; python666.cn 大家好&#xff0c;欢迎来到 Crossin的编程教室 &#xff01; 10月24号那天&#xff0c;也就是传说中的1024程序员节&#xff0c;我翻开日历的时候&#xff0c;看到一段代码&#xff1a; 说实话&#xf…

CPU就绪情况及其对虚拟机性能的影响

CPU就绪是虚拟化中的一种性能度量&#xff0c;用于指示物理CPU中的潜在问题&#xff0c;作为对系统效率的度量&#xff0c;它用于跟踪性能和资源利用率&#xff0c;并避免严重错误。为了理解它在管理虚拟机中的重要性&#xff0c;我们将探讨CPU就绪作为一种性能指标的作用。 让…

HarmonyOS(二)—— 初识ArkTS开发语言(中)之ArkTS的由来和演进

前言 在上一篇文章HarmonyOS&#xff08;二&#xff09;—— 初识ArkTS开发语言&#xff08;上&#xff09;之TypeScript入门&#xff0c;我初识了TypeScript相关知识点&#xff0c;也知道ArkTS是华为基于TypeScript发展演化而来。 从最初的基础的逻辑交互能力&#xff0c;到…

Python文件上传 【出错】

文件上传时选择相应文件&#xff0c;选择不到 需求&#xff1a;实现百度上传文件 Code # 无法选择文件 import os import time # import autoit from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChainsdriver webdriver.Chrome…

什么是文件安全

文件安全就是通过实施严格的访问控制措施和完美的权限卫生来保护您的业务关键信息不被窥探&#xff0c;除了启用和监控安全访问控制外&#xff0c;整理数据存储在保护文件方面也起着重要作用。通过清除旧的、过时的和其他垃圾文件来定期优化文件存储&#xff0c;以专注于关键业…

【51单片机】数码管与LCD1602(学习笔记)

一、静态数码管 1、数码管介绍 LED数码管&#xff1a;有多个发光二极管封装在一起的"8"字型的显示器 2、数码管引脚定义 分为&#xff1a;共阴极连接&#xff08;多&#xff09;、共阳极连接 图片仅供参考&#xff0c;以图纸为准 公共端&#xff1a;接地 > 供…

【数据结构与算法】排序二叉树的创建节点的添加和删除(附代码实现与代码讲解)

首先来了解下排序二叉树的基本概念 排序二叉树&#xff1a;任意一个根节点&#xff0c;比他的左子树中的任意节点都大&#xff0c;比他的右子树中的任意节点都小 比如下面的这个树就是排序二叉树 OK&#xff0c;在了解了这个基本概念之后&#xff0c;就可以去看下面的代码了 …

车载网络测试 - UDS诊断篇 - CAN与OSI七层模型

目录 为什么会介绍OSI七层模型&#xff1f; CAN规范与OSI模型 1、Physical Layer 1 2、Data Link Layer 2 3、Network Layer 3 & Transport Protocol Layer 4 4、Transport Protocol Layer 4 5、Session Layer 5 & Presentation Layer 6 & Application Laye…

【c++Leetcode】287. Find the Duplicate Number

问题入口 思想&#xff1a;Floyds Tortoise and Hare 这个算法除了可以检测是否有环&#xff08;问题入口&#xff09;&#xff0c;还可以用来检测重复数。当然这还需要一个慢指针才能实现。具体请点击标题跳转到原视频&#xff0c;这里是把内容再梳理一遍。如果有不对的地方…

多路转接之epoll

本篇博客介绍&#xff1a; 多路转接之epoll 多路转接之epoll 初识epollepoll相关系统调用epoll的工作原理epoll服务器编写成员变量构造函数 循环函数HandlerEvent函数epoll的优缺点 我们学习epoll分为四部分 快速理解部分概念 快速的看一下部分接口讲解epoll的工作原理手写epo…

Springboot 集成 Seata

Seata 是一款开源的分布式事务解决方案&#xff0c;致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式&#xff0c;为用户打造一站式的分布式解决方案。Seata官网 1.找到适合的Seata版本 参考&#xff1a;SpringCloudAlibaba S…

译文:我们如何使 Elasticsearch 7.11 中的 date_histogram 聚合比以往更快

这篇文章是ES7.11版本的文章&#xff0c;主要学习的是思路&#xff0c;记录在这里留作以后参考用。 原文地址&#xff1a;https://www.elastic.co/cn/blog/how-we-made-date-histogram-aggregations-faster-than-ever-in-elasticsearch-7-11 正文开始&#xff1a; Elasticsea…

美国Embarcadero产品经理Marco Cantù谈Delphi/C++ Builder目前开发应用领域

美国Embarcadero产品经理Marco Cant 日前在欧洲的一次信息技术会议上谈到了Delphi/C Builder目前开发应用领域&#xff1a;RAD Studio Delphi/C Builder目前应用于哪些开发领域&#xff1f;使用 Delphi 和 CBuilder 进行开发为当今众多企业提供了动力。 航空航天 大型数据采集 …

4.2 final关键字

思维导图&#xff1a; 4.2.1 final关键字修饰类 定义和基本概念&#xff1a; 在 Java 中&#xff0c;final关键字有“最终”或“不可改”的含义。使用final关键字修饰的元素&#xff08;类、方法或变量&#xff09;都有其特定的特性。 主要应用和注意事项&#xff1a; 修饰类&…

Spring - 手写模拟Spring底层原理

手写Spring 定义配置类AppConfig ComponentScan("com.spring.zsj") public class AppConfig {Beanpublic ApplicationListener applicationListener() {return new ApplicationListener() {Overridepublic void onApplicationEvent(ApplicationEvent event) {System…