当前位置: 首页 > news >正文

c++二叉树

二叉树进阶

1.二叉搜索树(binary search tree)

​ 二叉搜索树天然就适合查找,对于满二叉树或者完全二叉树,最多搜索lgn次(就像是有序数组二分查找,每次搜索都会减少范围),极端情况简化成单链表就要走n次,即要走高度次,时间复杂度是O(N)。所以需要用时间复杂度为O(lgn)的AVL树(平衡二叉树)或者RB树(红黑树)解决。

​ 按中序遍历,得到的结果就是有序的,升序;后序删除方便很多,不用保留前面的值;拷贝不可以调用插入,否则结构会发生巨大的变化,而是使用前序来赋值 。

​ 相较于普通的二叉树,增删查改就有了意义,而有序数组二分查找是不可以的,挪动数据效率很低。

​ 二叉搜索树不允许有重复,key一般要唯一。

1.1概念

二叉搜索树又称二叉排序树它或者是一棵空树,或者是具有以下性质的二叉树:

​ 1.若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 ;

​ 2.若它的右子树不为空,则右子树上所有节点的值都大于根节点的值 ;

​ 3.它的左右子树也分别为二叉搜索树;

2.二叉搜索树非递归模拟实现

#pragma once
#include <cassert>
namespace BinarySearchTree
{template <class K>struct BSTreeNode{BSTreeNode(const K &key = 0) : left_(nullptr), right_(nullptr), key_(key) {}BSTreeNode<K> *left_;BSTreeNode<K> *right_;K key_;};template <class K>class BSTree{// 内嵌类型typedef BSTreeNode<K> node;public:// 默认成员函数BSTree() : root_(nullptr){}~BSTree() {}public:// 普通成员函数bool insert(const K &key);void inorder(){_inorder(root_);}void _inorder(node *root);bool find(const K &key);bool erase(const K &key);private:// 成员变量node *root_;};template <class K>bool BSTree<K>::insert(const K &key){if (root_ == nullptr){root_ = new node(key);return true;}node *cur = root_;node *parent = root_;while (cur){if (cur->key_ == key){return false;}else if (key > cur->key_){parent = cur;cur = cur->right_;}else{parent = cur;cur = cur->left_;}}cur = new node(key);if (key > parent->key_){parent->right_ = cur;}else{parent->left_ = cur;}return true;}template <class K>void BSTree<K>::_inorder(BSTree<K>::node *root){if (root == nullptr){return;}_inorder(root->left_);cout << root->key_ << " ";_inorder(root->right_);}template <class K>bool BSTree<K>::find(const K &key){if (root_ == nullptr){return false;}node *cur = root_;while (cur){if (key == cur->key_){return true;}else if (key > cur->key_){cur = cur->right_;}else{cur = cur->left_;}}return false;}template <class K>bool BSTree<K>::erase(const K &key){node *cur = root_;node *parent = cur;while (cur){if (key == cur->key_){// 找到了,托孤要考虑删root;// 没有孩子,托孤nullptr// 有一个孩子,托孤if (cur->left_ == nullptr){if (cur == root_){parent = cur->right_;}else{if (key_ > parent->key_){parent->right_ = cur->right_;}else{parent->left_ = cur->right_;}}}else if (cur->right_ == nullptr){if (cur == root_){parent = cur->left_;}else{if (key_ > parent->key_){parent->right_ = cur->left_;}else{parent->left_ = cur->left_;}}}else // 有两个孩子,要取左子树最右或者右子树最左{node *leftmax = cur->left_; // 可能cur->left为leftmaxnode *pleftmax = cur;while (leftmax->right_){pleftmax = leftmax;leftmax = leftmax->right_;}std::swap(cur->key_, leftmax->key_);if (pleftmax->left_ == leftmax){pleftmax->left_ = leftmax->left_;}else{pleftmax->right_ = leftmax->left_;}cur = leftmax;}delete cur;return true;}else if (key > cur->key_){parent = cur;cur = cur->right_;}else{parent = cur;cur = cur->left_;}}return false;}}

3.二叉搜索树优点

​ 1.查找效率高;

​ 2.可以顺便实现排序,升序;

​ 3.插入删除效率都不错;

4.二叉搜索树递归实现

#pragma once
#include <cassert>
namespace BinarySearchTree
{template <class K>struct BSTreeNode{BSTreeNode(const K &key = 0) : left_(nullptr), right_(nullptr), key_(key) {}BSTreeNode<K> *left_;BSTreeNode<K> *right_;K key_;};template <class K>class BSTree{// 内嵌类型typedef BSTreeNode<K> node;public:// 默认成员函数BSTree() : root_(nullptr){}BSTree(const BSTree<K> &t){root_ = copy(t.root_);}BSTree<K> &operator=(BSTree<K> t){swap(*this, t);return *this;}~BSTree(){destroy(root_);}public:// 普通成员函数void swap(BSTree<K> &t);bool insert(const K &key){return _insert(root_, key);}void inorder(){_inorder(root_);cout << endl;}bool find(const K &key){return _find(root_, key);}bool erase(const K &key){return _erase(root_, key);}private:// 私有成员node *copy(node *root);void destroy(node *&root);bool _insert(node *&root, const K &key);bool _find(node *root, const K &key);void _inorder(node *root);bool _erase(node *&root, const K &key);node *root_;};template <class K>bool BSTree<K>::_insert(node *&root, const K &key){if (root == nullptr){root = new node(key);return true;}if (key > root->key_){return _insert(root->right_, key);}else if (key < root->key_){return _insert(root->left_, key);}else{return false;}}template <class K>void BSTree<K>::_inorder(node *root){if (root == nullptr){cout << "nullptr"<< " ";return;}_inorder(root->left_);cout << root->key_ << " ";_inorder(root->right_);}template <class K>bool BSTree<K>::_find(node *root, const K &key){if (root == nullptr){return false;}if (key > root->key_){return _find(root->right_, key);}else if (key < root->key_){return _find(root->left_, key);}else{return true;}}template <class K>bool BSTree<K>::_erase(node *&root, const K &key){if (root == nullptr){return false;}if (key > root->key_){return _erase(root->right_, key);}else if (key < root->key_){return _erase(root->left_, key);}else{node *del = root;if (root->left_ == nullptr){root = root->right_;}else if (root->right_ == nullptr){root = root->left_;}else{node *leftmax = root->left_;while (leftmax->right_){leftmax = leftmax->right_;}std::swap(leftmax->key_, root->key_);return _erase(root->left_, key);}delete del;return true;}}template <class K>void BSTree<K>::destroy(node *&root){if (root == nullptr){return;}destroy(root->left_);destroy(root->right_);delete root;root = nullptr;}template <class K>typename BSTree<K>::node *BSTree<K>::copy(node *root){if (root == nullptr){return nullptr;}node *newnode = new node(root->key_);newnode->left_ = copy(root->left_);newnode->right_ = copy(root->right_);return newnode;}template <class K>void BSTree<K>::swap(BSTree<K> &t){std::swap(root_, t.root_);}
}

5.二叉搜索树的应用场景

5.1key的搜索模型(在不在的场景)

​ 门禁系统、车辆输入系统、查找单词是否拼写错误,将词库放到一颗搜索树之中,然后find。

5.1key/value的搜索模型(通过一个值找另外一个值)

​ 手机号找快递信息、停车场(按时计费)、身份证检票查找车票信息,不用制造车票并往车票里写入信息;

namespace key_value
{template <class K, class V>struct BSTreeNode{BSTreeNode(const K &key = K(), const V &value = V()) : left_(nullptr), right_(nullptr), key_(key), value_(value) {}BSTreeNode<K, V> *left_;BSTreeNode<K, V> *right_;K key_;V value_;};template <class K, class V>class BSTree{// 内嵌类型public:typedef BSTreeNode<K, V> node;public:// 默认成员函数BSTree() : root_(nullptr){}~BSTree(){}public:// 普通成员函数bool insert(const K &key, const V &value){return _insert(root_, key, value);}void inorder(){_inorder(root_);cout << endl;}node *find(const K &key){return _find(root_, key);}bool erase(const K &key){return _erase(root_, key);}private:// 私有成员bool _insert(node *&root, const K &key, const V &value);node *_find(node *root, const K &key);void _inorder(node *root);bool _erase(node *&root, const K &key);node *root_;};template <class K, class V>bool BSTree<K, V>::_insert(node *&root, const K &key, const V &value){if (root == nullptr){root = new node(key, value);return true;}if (key > root->key_){return _insert(root->right_, key, value);}else if (key < root->key_){return _insert(root->left_, key, value);}else{return false;}}template <class K, class V>void BSTree<K, V>::_inorder(node *root){if (root == nullptr){return;}_inorder(root->left_);cout << root->key_ << " : " << root->value_ << "  ";_inorder(root->right_);}template <class K, class V>typename BSTree<K, V>::node *BSTree<K, V>::_find(node *root, const K &key){if (root == nullptr){return nullptr;}if (key > root->key_){return _find(root->right_, key);}else if (key < root->key_){return _find(root->left_, key);}else{return root;}}template <class K, class V>bool BSTree<K, V>::_erase(node *&root, const K &key){if (root == nullptr){return false;}if (key > root->key_){return _erase(root->right_, key);}else if (key < root->key_){return _erase(root->left_, key);}else{node *del = root;if (root->left_ == nullptr){root = root->right_;}else if (root->right_ == nullptr){root = root->left_;}else{node *leftmax = root->left_;while (leftmax->right_){leftmax = leftmax->right_;}std::swap(leftmax->key_, root->key_);return _erase(root->left_, key);}delete del;return true;}}
}

相关文章:

c++二叉树

二叉树进阶 1.二叉搜索树(binary search tree) ​ 二叉搜索树天然就适合查找&#xff0c;对于满二叉树或者完全二叉树&#xff0c;最多搜索lgn次(就像是有序数组二分查找&#xff0c;每次搜索都会减少范围)&#xff0c;极端情况简化成单链表就要走n次&#xff0c;即要走高度次…...

第19章-IPv6基础

1. IPv4的缺陷 2. IPv6的优势 3. 地址格式 3.1 格式 3.2 长度 4. 地址书写压缩 4.1 段内前导0压缩 4.2 全0段压缩 4.3 例子1 4.4 例子 5. 网段划分 5.1 前缀 5.2 接口标识符 5.3 前缀长度 5.4 地址规模分类 6. 地址分类 6.1 单播地址 6.2 组播地址 6.3 任播地址 6.4 例子 …...

浅谈人才招聘APP开发的解决方案

随着企业竞争加剧&#xff0c;高效、精准地招聘人才成为企业持续发展的关键。人才招聘系统能够简化招聘流程&#xff0c;提高效率&#xff0c;确保企业快速找到合适人才。同时&#xff0c;通过智能匹配和数据分析&#xff0c;提升招聘质量&#xff0c;优化候选人体验。因此&…...

大语言模型LLM推理加速:Hugging Face Transformers优化LLM推理技术(LLM系列12)

文章目录 大语言模型LLM推理加速:Hugging Face Transformers优化LLM推理技术(LLM系列12)引言Hugging Face Transformers库的推理优化基础模型级别的推理加速策略高级推理技术探索硬件加速与基础设施适配案例研究与性能提升效果展示结论与未来展望大语言模型LLM推理加速:Hug…...

JVM 第四部分—垃圾回收相关概念 2

System.gc() 在默认情况下&#xff0c;通过System.gc()或者Runtime.getRuntime().gc()的调用&#xff0c;会显式触发Full GC&#xff0c;同时对老年代和新生代进行回收&#xff0c;尝试释放被丢弃对象占用的内存 然而System.gc()调用附带一个免责声明&#xff0c;无法保证对垃…...

tritonserver学习之八:redis_caches实践

tritonserver学习之一&#xff1a;triton使用流程 tritonserver学习之二&#xff1a;tritonserver编译 tritonserver学习之三&#xff1a;tritonserver运行流程 tritonserver学习之四&#xff1a;命令行解析 tritonserver学习之五&#xff1a;backend实现机制 tritonserv…...

2024有哪些免费的mac苹果电脑深度清理工具?CleanMyMac X

苹果电脑用户们&#xff0c;你们是否经常感到你们的Mac变得不再像刚拆封时那样迅速、流畅&#xff1f;可能是时候对你的苹果电脑进行一次深度清理了。在这个时刻&#xff0c;拥有一些高效的深度清理工具就显得尤为重要。今天&#xff0c;我将介绍几款优秀的苹果电脑深度清理工具…...

UE5中实现后处理深度描边

后处理深度描边可以通过取得边缘深度变化大的区域进行描边&#xff0c;一方面可以用来做角色的等距内描边&#xff0c;避免了菲尼尔边缘光不整齐的问题&#xff0c;另一方面可以结合场景扫描等特效使用&#xff0c;达到更丰富的效果&#xff1a; 后来解决了开启TAA十字线和锯齿…...

Java面试值之集合

集合 1.HashMap底层?扩容机制?1.7-1.8的升级?2.HashMap的长度为什么是2的幂次方?3.HashMap 插入1.7和1.8的区别?4.什么是红黑树?O(logn)5.HashMap为什么会使用红黑树?6.ArrayList底层?扩容机制?7.LinkedList底层?扩容机制?8.ArrayList可以序列化,但是为什么不直接序…...

React之组件定义和事件处理

一、组件的分类 在react中&#xff0c;组件分为函数组件和class组件&#xff0c;也就是无状态组件和有状态组件。 * 更过时候我们应该区别使用无状态组件&#xff0c;因为如果有状态组件会触发生命周期所对应的一些函数 * 一旦触发他生命周期的函数&#xff0c;它就会影响当前项…...

LeetCode -55 跳跃游戏

LeetCode -55 跳跃游戏 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。…...

Android和Linux的嵌入式开发差异

最近开始投入Android的怀抱。说来惭愧&#xff0c;08年就听说这东西&#xff0c;当时也有同事投入去看&#xff0c;因为恶心Java&#xff0c;始终对这玩意无感&#xff0c;没想到现在不会这个嵌入式都快要没法搞了。为了不中年失业&#xff0c;所以只能回过头又来学。 首先还是…...

关于Node.js异常处理的教程

在Node.js开发中&#xff0c;异常处理是非常重要的一部分。良好的异常处理可以帮助我们及时发现和解决问题&#xff0c;提高系统的稳定性和可靠性。本教程将向您介绍Node.js中异常处理的最佳实践和策略。 1. 使用try-catch捕获同步异常 在Node.js中&#xff0c;可以使用try-c…...

13. Springboot集成Protobuf

目录 1、前言 2、Protobuf简介 2.1、核心思想 2.2、Protobuf是如何工作的&#xff1f; 2.3、如何使用 Protoc 生成代码&#xff1f; 3、Springboot集成 3.1、引入依赖 3.2、定义Proto文件 3.3、Protobuf生成Java代码 3.4、配置Protobuf的序列化和反序列化 3.5、定义…...

Spring: Springboot 框架集成不同版本的spring redis

文章目录 一、集成不同版本的spring redis1、Spring Data Redis 1.x&#xff1a;2、Spring Data Redis 2.x&#xff1a;3、Spring Data Redis 3.x&#xff08;Spring Boot 2.x&#xff09;&#xff1a; 二、springboot集成Spring Data Redis 2.x1、首先&#xff0c;确保在 pom.…...

学习JAVA的第八天(基础)

目录 多态 前提 形式 测试类 调用成员的特点 优势 劣势 包 注意事项&#xff1a; final关键字 常量 命名规范&#xff1a; 注意事项&#xff1a; 权限修饰符 分类 代码块 局部代码块 构造代码块 静态代码块 抽象类 抽象类&#xff1a; 定义格式 抽象…...

【硬件相关】IB网/以太网基础介绍及部署实践

文章目录 一、前言1、Infiniband网络1.1、网络类型1.2、网络拓扑1.3、硬件设备1.3.1、网卡1.3.2、连接线缆a、光模块b、线缆 1.3.4、交换机 2、Ethernet网络 二、部署实践&#xff08;以太网&#xff09;1、Intel E810-XXVDA21.1、网卡信息1.2、检查命令1.2、驱动编译 2、Mella…...

【JavaEE】_Spring MVC项目之建立连接

目录 1. Spring MVC程序编写流程 2. 建立连接 2.1 RequestMapping注解介绍 2.2 RequestMapping注解使用 2.2.1 仅修饰方法 2.2.2 修饰类与方法 2.3 关于POST请求与GET请求 2.3.1 GET请求 2.3.2 POST请求 2.3.3 限制请求方法 1. Spring MVC程序编写流程 1. 建立连接&…...

【JavaEE进阶】 Spring AOP源码简单剖析

文章目录 &#x1f343;前言&#x1f340;Spring AOP源码剖析⭕总结 &#x1f343;前言 前面的博客中&#xff0c;博主对代理模式进行了一个简单的讲解&#xff0c;接下来博主将对Spring AOP源码进行简单剖析&#xff0c;使我们对Spring AOP了解的更加深刻。 &#x1f340;Sp…...

Redis--内存回收机制详解

什么是内存回收机制? 众所周知Redis之所以性能高是因为数据都存在内存中&#xff0c;内存是很宝贵的&#xff0c;Redis的内存回收机制本质就是处理达到过期时间的key-value&#xff0c;以及当内存到达最大使用值时候触发的内存淘汰策略。 Redis数据删除的策略有哪些&#xf…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&am…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

iview框架主题色的应用

1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题&#xff0c;无需引入&#xff0c;直接可…...

PostgreSQL 与 SQL 基础:为 Fast API 打下数据基础

在构建任何动态、数据驱动的Web API时&#xff0c;一个稳定高效的数据存储方案是不可或缺的。对于使用Python FastAPI的开发者来说&#xff0c;深入理解关系型数据库的工作原理、掌握SQL这门与数据库“对话”的语言&#xff0c;以及学会如何在Python中操作数据库&#xff0c;是…...