C++二叉搜索树查找,插入,删除

devtools/2025/3/1 16:20:13/

二叉搜索树(Binary Search Tree, BST)是一种二叉树,每个节点包含一个键值,并且具有以下特性:

  • 左子树的所有节点的键值都小于当前节点的键值。
  • 右子树的所有节点的键值都大于当前节点的键值。
  • 每个节点的左右子树都是二叉搜索树。

在BST中,查找、插入和删除操作的时间复杂度通常为 (O(\log n)),其中 (n) 是树中的节点数。这是因为在理想情况下,树的高度是对数级别的。

接下来我将写一个基本的二叉搜索树实现,包括查找、插入和删除操作,并说明其原理。

查找操作

查找操作是根据键值在树中查找目标节点。由于BST的特性,可以根据目标键值与当前节点键值的比较,决定是向左子树还是右子树递归查找。

插入操作

插入操作是通过查找空位置来插入新的节点。首先从根节点开始,沿着树的路径向下查找,找到一个空位置后插入节点。

删除操作

删除操作分为三种情况:

  1. 删除的节点是叶子节点:直接删除该节点。
  2. 删除的节点有一个子节点:将该节点的父节点指向其唯一的子节点。
  3. 删除的节点有两个子节点:此时我们找到该节点的中序后继节点(右子树中最小的节点),用它的值替代被删除节点的值,然后删除后继节点。

C++代码实现

#include <iostream>
using namespace std;// 二叉搜索树节点结构
struct TreeNode {int value;TreeNode* left;TreeNode* right;TreeNode(int val) : value(val), left(nullptr), right(nullptr) {}
};// 查找操作
TreeNode* search(TreeNode* root, int key) {if (root == nullptr || root->value == key)return root;if (key < root->value)return search(root->left, key);elsereturn search(root->right, key);
}// 插入操作
TreeNode* insert(TreeNode* root, int key) {if (root == nullptr)return new TreeNode(key);if (key < root->value)root->left = insert(root->left, key);elseroot->right = insert(root->right, key);return root;
}// 删除操作
TreeNode* deleteNode(TreeNode* root, int key) {if (root == nullptr) return root;if (key < root->value)root->left = deleteNode(root->left, key);else if (key > root->value)root->right = deleteNode(root->right, key);else {// 如果节点只有一个子树或者没有子树if (root->left == nullptr) {TreeNode* temp = root->right;delete root;return temp;}else if (root->right == nullptr) {TreeNode* temp = root->left;delete root;return temp;}// 如果节点有两个子树TreeNode* temp = minValueNode(root->right); // 找到右子树的最小节点root->value = temp->value; // 替换值root->right = deleteNode(root->right, temp->value); // 删除后继节点}return root;
}// 查找右子树最小的节点
TreeNode* minValueNode(TreeNode* node) {TreeNode* current = node;while (current && current->left != nullptr)current = current->left;return current;
}// 中序遍历
void inorder(TreeNode* root) {if (root != nullptr) {inorder(root->left);cout << root->value << " ";inorder(root->right);}
}int main() {TreeNode* root = nullptr;// 插入一些节点root = insert(root, 50);root = insert(root, 30);root = insert(root, 20);root = insert(root, 40);root = insert(root, 70);root = insert(root, 60);root = insert(root, 80);cout << "中序遍历结果:";inorder(root);cout << endl;// 查找节点TreeNode* found = search(root, 40);if (found != nullptr)cout << "找到节点: " << found->value << endl;elsecout << "未找到节点" << endl;// 删除节点root = deleteNode(root, 20);cout << "删除节点 20 后的中序遍历:";inorder(root);cout << endl;return 0;
}

代码解析

  1. 查找操作:从根节点开始,如果要查找的键值比当前节点小,则向左子树递归查找;如果大于当前节点,则向右子树递归查找。时间复杂度是 (O(\log n)),因为树的高度为对数级别。

  2. 插入操作:插入时同样从根节点开始,找到合适的位置(空位置),然后插入节点。时间复杂度同样是 (O(\log n))。

  3. 删除操作

    • 当删除的节点只有一个子节点或没有子节点时,直接删除该节点并连接父节点。
    • 当删除的节点有两个子节点时,找到该节点的中序后继(右子树最小节点),将其值替代删除节点的值,然后删除中序后继节点。
  4. 中序遍历:中序遍历BST会得到从小到大的节点值。

时间复杂度分析

  • 查找:每次比较一个节点,沿着树的深度向下查找。树的高度为 (O(\log n)),所以查找操作的时间复杂度是 (O(\log n))。
  • 插入:插入操作本质上是查找操作的扩展,时间复杂度是 (O(\log n))。
  • 删除:删除操作中,最复杂的情况是删除有两个子节点的节点,需要找到右子树中的最小节点,时间复杂度是 (O(\log n))。

然而,如果树的高度变得不平衡,可能会退化成链表,此时时间复杂度变为 (O(n))。为了避免这种情况,可以使用平衡二叉树(如AVL树或红黑树)。


http://www.ppmy.cn/devtools/163671.html

相关文章

【详细讲解在STM32的UART通信中使用DMA机制】

详细讲解在STM32的UART通信中使用DMA机制 目录 详细讲解在STM32的UART通信中使用DMA机制一、DMA机制概述二、DMA在UART中的作用三、DMA的配置步骤四、UART初始化与DMA结合五、DMA传输的中断处理六、DMA与中断的结合使用七、注意事项与常见问题八、代码示例九、总结 一、DMA机制…

基于 kotlin版本的 Android的MVI架构

从双向绑定到单向数据流 何为MVI&#xff1f; MVI即Model-View-Intent&#xff0c;它受Cycle.js前端框架的启发&#xff0c;提倡一种单向数据流的设计思想&#xff0c;非常适合数据驱动型的UI展示项目&#xff1a; Model: 与其他MVVM中的Model不同的是&#xff0c;MVI的Model…

013作用域

一、基本概念 C语言中&#xff0c;标识符都有一定的可见范围&#xff0c;这些可见范围保证了标识符只能在一个有限的区域内使用&#xff0c;这个可见范围&#xff0c;被称为作用域&#xff08;scope&#xff09;。 软件开发中&#xff0c;尽量缩小标识符的作用域是一项基本原…

AIGC生图产品PM必须知道的Lora训练知识!

hihi&#xff0c;其实以前在方向AIGC生图技术原理和常见应用里面已经多次提到Lora的概念了&#xff0c;但是没有单独拿出来讲过&#xff0c;今天就耐心来一下&#xff01; &#x1f525; 一口气摸透AIGC文生图产品SD&#xff08;Stable Diffusion&#xff09;&#xff01; 一、…

【JavaWeb13】了解ES6的核心特性,对于提高JavaScript编程效率有哪些潜在影响?

文章目录 &#x1f30d;一. ES6 新特性❄️1. ES6 基本介绍❄️2. 基本使用2.1 let 声明变量2.2 const 声明常量/只读变量2.3 解构赋值2.4 模板字符串2.5 对象拓展运算符2.6 箭头函数 &#x1f30d;二. Promise❄️1. 基本使用❄️2. 如何解决回调地狱问题2.1回调地狱问题2.2 使…

计算机毕业设计Python+DeepSeek-R1大模型考研院校推荐系统 考研分数线预测 考研推荐系统 考研(源码+文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

拍照自带解说?水印相机,让CAD照片标注“开口说话”!

在施工造价等领域的工作中&#xff0c;现场图片与图纸的结合使用是非常常见的场景。以往&#xff0c;我们可能会花费大量时间去整理和标记图片&#xff0c;以便与图纸准确对应。 现在&#xff0c;借助CAD快速看图-水印相机功能&#xff0c;这些问题都能轻松解决&#xff01; …

fastadmin 后台sku 插件

老规矩先上效果图 新引用需要用到的js define([backend], function (Backend) {require.config({paths: {// vue: ../js/vue,//js省略&#xff0c;如果是vue.min.js&#xff0c;就学vue.minlayui: /assets/LayuiSpzj/layui/layui,//js省略&#xff0c;如果是vue.min.js&#x…