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

C++------利用C++实现二叉搜索树【数据结构】

文章目录

  • 二叉搜索树
    • 概念
    • 二叉搜索树的操作
      • 查找
      • 插入
      • 删除
    • 二叉搜索树的应用

二叉搜索树

概念

什么是二叉搜索树,二叉搜索树就是指左孩子永远比根小右孩子永远比根大。这个规则适用于所有的子树。
在这里插入图片描述
上面的就是一棵二叉搜索树,我们还可以发现这棵树走一个中序遍历序列是有序的,所以它又被称为二叉排序树。

二叉搜索树的操作

二叉搜索树的操作主要分为以下几点,查找, 插入,删除。

查找

算法思想:二叉搜索树的查找算法是这样的,从根的地方开始找,如果要找的key比根大就到右子树去找,如果比根小就到左子树找。时间复杂度最差为O(N)最优为O(logn),如果一棵树走完了还没有找到说明这个数字不在这棵树内。
O(N)时间复杂度是下面这棵树的查找产生的。
在这里插入图片描述
我们要使树的高度保持为logN就必须引入平衡二叉搜索树的概念,这个部分我们在后面的AVL和红黑树部分讲解。
非递归算法:

	bool Find(const K& key){Node* cur = _root;while (cur != nullptr){if (cur->_key > key){cur = cur->_left;}else if (cur->_key < key){cur = cur->_right;}else{return true;}}return false;}

递归算法:
key小于就递归找左树,大于就递归找右树

	bool _FindR(Node* root, const K& key){if (root == nullptr){return false;}if (root->_key < key){_FindR(root->_right, key);}else if (root->_key > key){_FindR(root->_left, key);}else{return true;}}

插入

插入分为两种情况:
1、如果树为空,则直接新增节点,赋值给_root指针。
2、树不为空,按二叉搜索树性质查找插入位置,插入新节点。
在这里插入图片描述
非递归算法

bool Insert(const K& key){if (_root == nullptr){_root = new Node(key);return true;}Node* cur = _root;Node* parent = nullptr;while (cur){if (cur->_key < key){parent = cur;cur = cur->_right;}else if (cur->_key > key){parent = cur;cur = cur->_left;}else{return false;}}cur = new Node(key);if (parent->_key < key){parent->_right = cur;}else{parent->_left = cur;}return true;}

递归算法

		bool _InsertR(Node*& root, const K& key){if (root == nullptr){root = new Node(key);return true;}if (root->_key > key){return _InsertR(root->_left, key);}else if (root->_key < key){return _InsertR(root->_right, key);}else{return false;}}

删除

首先查找元素是否在二叉搜索树中,如果不存在,则返回,否则要删除的节点可能分下面四种情况:
a.要删除的节点无孩子节点
b.要删除的节点只有左孩子节点
c.要删除的节点只有右孩子节点
d.要删除的节点有左右孩子节点
情况b,c可以合成一个情况,那就是只有一个孩子节点。
情况b:删除该节点且是被删除节点的双亲节点指向被删除节点的左孩子节点—直接删除
在这里插入图片描述

情况c:删除该节点且是被删除节点的双亲节点指向被删除节点的右孩子节点—直接删除
在这里插入图片描述

情况d:在它的左子树中寻找最大节点,用它的值填补到被删除节点中,再来处理该节点的删除问题—替换法删除。
在这里插入图片描述
非递归算法:

bool Erase(const K& key){Node* cur = _root;Node* parent = nullptr;while (cur){if (cur->_key > key){parent = cur;cur = cur->_left;}else if (cur->_key < key){parent = cur;cur = cur->_right;}else{//左边为空if (cur->_left == nullptr){if (cur == _root){_root = cur->_right;}else{if (parent->_right == cur){parent->_right = cur->_right;}else{parent->_left = cur->_right;}}}else if (cur->_right == nullptr){if (cur == _root){_root = cur->_left;}else{if (parent->_right == cur){parent->_right = cur->_left;}else{parent->_left = cur->_left;}}}else{//左右都不为空//找到左树中的最大值为替代节点Node* parent = cur;Node* leftmax = _root->_left;while (leftmax->_right != nullptr){parent = leftmax;leftmax = leftmax->_right;}swap(cur->_key, leftmax->_key);if (parent->_left == leftmax){parent->_left = leftmax->_left;}else{parent->_right = leftmax->_left;}cur = leftmax;}delete cur;return true;}}return false;}

非递归算法:

//Node*& 引用是关键,没有引用就不会链接起来,不用引用也可以用二级指针。
bool _EraseR(Node*& root, const K& key){if (root == nullptr){return false;}if (root->_key < key){return _EraseR(root->_right, key);}else if (root->_key > key){return _EraseR(root->_left, key);}else{Node* del = root;//1、左为空//2、右为空//3、左右都不为空if (root->_left == nullptr){root = root->_right;}else if (root->_right == nullptr){root = root->_left;}else{Node* leftMax = root->_left;while (leftMax->_left){leftMax = leftMax->_right;}swap(root->_key, leftMax->_key);return _EraseR(root->_left, key);}delete del;return true;}}

完整代码

namespace name
{template<class K>struct BSTreeNode{BSTreeNode<K>* _left;BSTreeNode<K>* _right;K _key;BSTreeNode(const K& key):_left(nullptr), _right(nullptr), _key(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(_root, t._root);return *this;}~BSTree(){Destory(_root);}bool Insert(const K& key){if (_root == nullptr){_root = new Node(key);return true;}Node* cur = _root;Node* parent = nullptr;while (cur){if (cur->_key < key){parent = cur;cur = cur->_right;}else if (cur->_key > key){parent = cur;cur = cur->_left;}else{return false;}}cur = new Node(key);if (parent->_key < key){parent->_right = cur;}else{parent->_left = cur;}return true;}bool Find(const K& key){Node* cur = _root;while (cur != nullptr){if (cur->_key > key){cur = cur->_left;}else if (cur->_key < key){cur = cur->_right;}else{return true;}}return false;}bool Erase(const K& key){Node* cur = _root;Node* parent = nullptr;while (cur){if (cur->_key > key){parent = cur;cur = cur->_left;}else if (cur->_key < key){parent = cur;cur = cur->_right;}else{//左边为空if (cur->_left == nullptr){if (cur == _root){_root = cur->_right;}else{if (parent->_right == cur){parent->_right = cur->_right;}else{parent->_left = cur->_right;}}}else if (cur->_right == nullptr){if (cur == _root){_root = cur->_left;}else{if (parent->_right == cur){parent->_right = cur->_left;}else{parent->_left = cur->_left;}}}else{//左右都不为空//找到左树中的最大值为替代节点Node* parent = cur;Node* leftmax = _root->_left;while (leftmax->_right != nullptr){parent = leftmax;leftmax = leftmax->_right;}swap(cur->_key, leftmax->_key);if (parent->_left == leftmax){parent->_left = leftmax->_left;}else{parent->_right = leftmax->_left;}cur = leftmax;}delete cur;return true;}}return false;}void Inorder(){_Inorder(_root);cout << endl;}bool FindR(const K& key){return _FindR(_root, key);}bool InsertR(const K& key){return _InsertR(_root, key);}bool EraseR(const K& key){return _EraseR(_root, key);}private:void Destory(Node* root){if (root == nullptr){return;}Destory(root->_left);Destory(root->_right);delete root;root = nullptr;}Node* Copy(Node* root){if (root == nullptr){return nullptr;}Node* copyroot = new Node(root->_key);copyroot->_left = Copy(root->_left);copyroot->_right = Copy(root->_right);return copyroot;}bool _InsertR(Node*& root, const K& key){if (root == nullptr){root = new Node(key);return true;}if (root->_key > key){return _InsertR(root->_left, key);}else if (root->_key < key){return _InsertR(root->_right, key);}else{return false;}}bool _FindR(Node* root, const K& key){if (root == nullptr){return false;}if (root->_key < key){_FindR(root->_right, key);}else if (root->_key > key){_FindR(root->_left, key);}else{return true;}}bool _EraseR(Node*& root, const K& key){if (root == nullptr){return false;}if (root->_key < key){return _EraseR(root->_right, key);}else if (root->_key > key){return _EraseR(root->_left, key);}else{Node* del = root;//1、左为空//2、右为空//3、左右都不为空if (root->_left == nullptr){root = root->_right;}else if (root->_right == nullptr){root = root->_left;}else{Node* leftMax = root->_left;while (leftMax->_left){leftMax = leftMax->_right;}swap(root->_key, leftMax->_key);return _EraseR(root->_left, key);}delete del;return true;}}void _Inorder(Node* root){if (root == nullptr){return;}_Inorder(root->_left);cout << root->_key << " ";_Inorder(root->_right);}Node* _root;};
}

二叉搜索树的应用

应用主要是分为了K模型和KV模型,后面的set为K模型,map为KV模型,具体是这样的:

  1. K模型:K模型即只有key作为关键码,结构中只需要存储Key即可,关键码即为需要搜索到 的值。 比如:给一个单词word,判断该单词是否拼写正确,具体方式如下: 以词库中所有单词集合中的每个单词作为key,构建一棵二叉搜索树
    在二叉搜索树中检索该单词是否存在,存在则拼写正确,不存在则拼写错误。
  2. KV模型:每一个关键码key,都有与之对应的值Value,即<Key, Value>的键值对。该种方式在现实生活中非常常见: 比如英汉词典就是英文与中文的对应关系,通过英文可以快速找到与其对应的中文,英 文单词与其对应的中文<word,chinese>就构成一种键值对; 再比如统计单词次数,统计成功后,给定单词就可快速找到其出现的次数,单词与其出现次数就是<word,count>就构成一种键值对。
    上面的代码时K模型的,下面的代码时KV模型的。
namespace name1
{template<class K,class V>struct BSTreeNode{BSTreeNode<K,V>* _left;BSTreeNode<K,V>* _right;K _key;V _value;BSTreeNode(const K& key,const V& value):_left(nullptr),_right(nullptr),_key(key),_value(value){}};template <class K,class V>class BSTree{typedef BSTreeNode<K,V> Node;public://构造函数BSTree():_root(nullptr){}BSTree(const BSTree<K,V>& t){_root = Copy(t._root);}BSTree<K,V>& operator=(BSTree<K,V> t){swap(_root, t._root);return *this;}~BSTree(){Destory(_root);}void Inorder(){_Inorder(_root);cout << endl;}Node* FindR(const K& key){return _FindR(_root,key);}bool InsertR(const K& key,const V& value){return _InsertR(_root, key,value);}bool EraseR(const K& key){return _EraseR(_root, key);}private:void Destory(Node* root){if (root == nullptr){return;}Destory(root->_left);Destory(root->_right);delete root;root = nullptr;}Node* Copy(Node* root){if (root == nullptr){return nullptr;}Node* copyroot = new Node(root->_key);copyroot->_left = Copy(root->_left);copyroot->_right = Copy(root->_right);return copyroot;}bool _InsertR(Node*& root,const K& key,const V& value){if (root == nullptr){root = new Node(key,value);return true;}if (root->_key > key){return _InsertR(root->_left, key, value);}else if (root->_key < key){return _InsertR(root->_right, key, value);}else{return false;}}Node* _FindR(Node* root, const K& key){if (root == nullptr){return nullptr;}if (root->_key < key){return _FindR(root->_right, key);}else if (root->_key > key){return _FindR(root->_left, key);}else{return root;}}bool _EraseR(Node*& root, const K& key){if (root == nullptr){return false;}if (root->_key < key){return _EraseR(root->_right, key);}else if (root->_key > key){return _EraseR(root->_left, key);}else{Node* del = root;//1、左为空//2、右为空//3、左右都不为空if (root->_left == nullptr){root = root->_right;}else if (root->_right == nullptr){root = root->_left;}else{Node* leftMax = root->_left;while (leftMax->_left){leftMax = leftMax->_right;}swap(root->_key, leftMax->_key);return _EraseR(root->_left, key);}delete del;return true;}}void _Inorder(Node* root){if (root==nullptr){return;}_Inorder(root->_left);cout << root->_key << ":" << root->_value << endl;_Inorder(root->_right);}Node* _root;};
}

KV模型的测试:

void Test_BSTree7()
{string arr[] = { "西瓜", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };name1::BSTree<string, int> countTree;for (auto& str : arr){//没有找到证明是第一次出现auto ret = countTree.FindR(str);if (ret == nullptr){countTree.InsertR(str, 1);}else{ret->_value++;}}countTree.Inorder();
}
int main()
{//Test_BSTree();//Test_BSTree1();//Test_BSTree2();//Test_BSTree3();//Test_BSTree4();//Test_BSTree5();//Test_BSTree6();Test_BSTree7();return 0;
}

在这里插入图片描述
好的我们下一篇再见!

相关文章:

C++------利用C++实现二叉搜索树【数据结构】

文章目录 二叉搜索树概念二叉搜索树的操作查找插入删除 二叉搜索树的应用 二叉搜索树 概念 什么是二叉搜索树&#xff0c;二叉搜索树就是指左孩子永远比根小右孩子永远比根大。这个规则适用于所有的子树。 上面的就是一棵二叉搜索树&#xff0c;我们还可以发现这棵树走一个中…...

HotSpot虚拟机之内存模型与线程安全

目录 一、线程内存模型 1. 内存模型 2. 内存模型操作 二、Happens-Before原则 三、Java线程 1. 线程实现方式 2. Java线程状态 四、Java线程安全 1. 线程安全程度 2. 锁优化 五、参考资料 一、线程内存模型 1. 内存模型 内存模型主要目的是定义共享变量的访问规则&…...

TiDB 多集群告警监控-中章-融合多集群 Grafana

作者&#xff1a; longzhuquan 原文来源&#xff1a; https://tidb.net/blog/ac730b0f 背景 随着公司XC改造步伐的前进&#xff0c;越来越多的业务选择 TiDB&#xff0c;由于各个业务之间需要物理隔离&#xff0c;避免不了的 TiDB 集群数量越来越多。虽然每套 TiDB 集群均有…...

【图像分类】基于卷积神经网络和主动学习的高光谱图像分类(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

notepad++ verilog关键字自动补全

新建verilog.xml放在安装目录下 D:\Program Files (x86)\Notepad\autoCompletion <?xml version"1.0" encoding"Windows-1252" ?> <NotepadPlus><AutoComplete><KeyWord name"accept_on" /><KeyWord name"a…...

C语言知识

C语言知识 链接 C语言中的数组初始化是有三种形式的&#xff0c;分别是&#xff1a; (1)数据类型 数组名称[长度n] {元素1,元素2…元素n}; (2)数据类型 数组名称[] {元素1,元素2…元素n}; (3)数据类型 数组名称[长度n]; 数组名称[0] 元素1; 数组名称[1] 元素2; 数组…...

数据结构基础

将节点构建成树 数据的结构逻辑结构集合线性结构树形结构图状结构 存储结构合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如…...

深度学习中数据处理相关的技巧

文章目录 提取隐蔽特征惰性加载数据集类别分布不均衡 提取隐蔽特征 在某些任务中&#xff0c;一些类别的特征可能相对较为罕见或难以捕捉。由于这些特征在数据集中出现的频率较低&#xff0c;模型可能无法充分学习它们&#xff0c;从而导致对这些类别的辨别能力较弱。为了解决…...

wkhtmltopdf 与 .Net Core

wkhtmltopdf 是使用webkit引擎转化为pdf的开源小插件. 其有.NET CORE版本的组件,DinkToPdf,但该控件对跨平台支持有限 。 是由于各系统平台会产生不同的编译结果,故windows上使用.dll,而Linux上的动态链接库是.so 所以你需要在Linux系统上安装相关wkhtmltox软件。 我这里准备了…...

Linux Mint 21.3 计划于 2023 年圣诞节发布

Linux Mint 项目近日公布了基于 Ubuntu 的 Linux Mint 发行版下一个重要版本的一些初步细节&#xff0c;以及备受期待的基于 Debian 的 LMDE 6&#xff08;Linux Mint Debian Edition&#xff09;版本。 近日&#xff0c;Linux Mint 项目负责人克莱门特-勒菲弗&#xff08;Clem…...

腾讯云3年轻量应用服务器2核4G5M和2核2G4M详细介绍

腾讯云轻量应用服务器3年配置&#xff0c;目前可以选择三年的轻量配置为2核2G4M和2核4G5M&#xff0c;2核2G4M和2核4G5M带宽&#xff0c;当然也可以选择选一年&#xff0c;第二年xufei会比较gui&#xff0c;腾讯云百科分享腾讯云轻量应用服务器3年配置表&#xff1a; 目录 腾…...

rabbitmq中的消息确认

如何保证消息被全部消费 应用场景&#xff1a;我们不想丢失任何任务消息。如果一个工作者&#xff08;worker&#xff09;挂掉了&#xff0c;我们希望任务会重新发送给其他的工作者&#xff08;worker&#xff09;。 为了防止消息丢失&#xff0c;RabbitMQ提供了消息响应&…...

jenkins一键部署github项目

个人目前理解jenkins部署分为两步&#xff1a; 构建项目&#xff0c;如生成jar自动执行sh脚本 如果没有jenkins&#xff0c;我们可能需要将jar移动到服务器&#xff0c;然后执行java -jar跑程序&#xff0c;jenkins可以替代我们执行这些东西&#xff0c;下面从0开始&#xff0…...

岩土工程安全监测隧道中使用振弦采集仪注意要点?

岩土工程安全监测隧道中使用振弦采集仪注意要点&#xff1f; 岩土工程的安全监测是非常重要的&#xff0c;它可以帮助工程师及时发现可能存在的问题&#xff0c;并及时解决&#xff0c;保障施工进度以及施工质量&#xff0c;保障工程的安全运行。其中&#xff0c;振弦采集仪是…...

第四章nginx组件精讲

nginx配件location匹配的规则和优先级&#xff08;重点面试题&#xff09; RUI&#xff1a;统一资源标识符&#xff0c;是一种字符串标识&#xff0c;用于标识抽象的或者物理资源&#xff08;文件&#xff0c;图片&#xff0c;视频&#xff09; nginx当中&#xff1a;uri ww…...

LlamaGPT -基于Llama 2的自托管类chatgpt聊天机器人

LlamaGPT一个自托管、离线、类似 ChatGPT 的聊天机器人&#xff0c;由 Llama 2 提供支持。100% 私密&#xff0c;不会有任何数据离开你的设备。 推荐&#xff1a;用 NSDT编辑器 快速搭建可编程3D场景 1、如何安装LlamaGPT LlamaGPT可以安装在任何x86或arm64系统上。 首先确保…...

常见的跨域解决方案

常见的跨域解决方案&#xff1a; 跨域问题可以分为两种情况&#xff1a;前端跨域和后端跨域。以下是针对这两种情况的跨域解决方案&#xff1a; 前端跨域解决方案&#xff1a; JSONP&#xff1a; 适用于前端向不同域名下的服务器请求数据&#xff0c;通过添加回调函数名称来…...

分布式websocket解决方案

1、websocket问题由来 websocket基础请自行学习,本文章是解决在分布式环境下websocket通讯问题。 在单体环境下,所有web客户端都是连接到某一个微服务上,这样消息都是到达统一服务端,并且也是由一个服务端进行响应,所以不会出现问题。 但是在分布式环境下,我们很容易发现…...

奥威BI财务数据分析方案:借BI之利,成就智能财务分析

随着智能技术的发展&#xff0c;各行各业都走上借助智能技术高效运作道路&#xff0c;财务数据分析也不例外。借助BI商业智能技术能够让财务数据分析更高效、便捷、直观立体&#xff0c;也更有助于发挥财务数据分析作为企业经营管理健康晴雨表的作用。随着BI财务数据分析经验的…...

Android12之com.android.media.swcodec无法生成apex问题(一百六十三)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…...

Xcode build和version

参考 一个叫做Version&#xff0c;一个叫做Build&#xff0c;&#xff08;version是版本号&#xff0c;build是打正式包每次Archive时的都增加的值&#xff09;这两个值都可以在Xcode中选中target&#xff0c;点击“Summary”后看到。 Version在plist文件中的key是“CFBundleSh…...

前端面试:【原型链】代码世界的家族传承

嗨&#xff0c;亲爱的代码探险家&#xff01;在JavaScript的奇妙世界里&#xff0c;有一个令人惊叹的概念&#xff0c;那就是原型链。这个概念就像是代码世界的家族传承&#xff0c;允许对象之间分享属性和方法&#xff0c;让你的代码更加高效和灵活。 1. 什么是原型链&#xf…...

2D应用开发是选择WebGL 还是选择Canvas?

推荐&#xff1a;使用 NSDT场景编辑器 助你快速搭建可二次编辑的3D应用场景 在介绍WebGL和Canvas的区别和联系之前&#xff0c;需要先了解它们各自的定义和特点。 WebGL是一种基于标准HTML5的技术&#xff0c;用于在Web浏览器中实时渲染3D图形。它是由Khronos Group开发的一套…...

Android Framework 常见解决方案(20)UDP广播无效问题

1 现象描述和原理解读 该问题同时存在于android App和Framework系统中。最终效果是在Android系统中直接使用UDP广播无效&#xff0c;有意思的是有的android系统可以&#xff0c;有的Android 系统不行。然而该部分代码自己在Linux上测试时是有效的&#xff0c;代码不变&#xf…...

VINS-Mono中的边缘化与滑窗 (4)——VINS边缘化为何是局部变量边缘化?

文章目录 0.前言1.系统构建1.1.仿真模型1.2.第一次滑窗优化1.3.第二次全局优化 2.边缘化时不同的舒尔补方式2.1.边缘化时舒尔补的意义2.2.不同的边缘化方式 3.边缘化时不同的舒尔补方式实验验证3.1.全局schur的操作方式3.2.VIO或VINS中局部边缘化的方式3.3.两种方式和全局优化方…...

真·VB.NET彻底释放Interop.Excel对象

使用 Microsoft.Office.Interop.Excel 虽然有速度慢的缺点&#xff1b;但是作为自带引用&#xff0c;兼容性最好&#xff0c;而且是COM对象模型也很熟悉(Excel里直接录个宏&#xff0c;很方便把VBA代码转成VB.NET)。所以处理几百上千条的小数据时还是很方便的。 而 Microsoft.…...

记录hutool http通过代理模式proxy访问外面的链接

效果&#xff1a; 代码&#xff1a; public class TestMain {public static void main(String[] args){HttpRequest httpRequest HttpRequest.get("https://www.youtube.com").timeout(30000);httpRequest.setProxy(new Proxy(Proxy.Type.HTTP,new InetSocketAddre…...

Selenium 自动化 | 案例实战篇

Chrome DevTools 简介 Chrome DevTools 是一组直接内置在基于 Chromium 的浏览器&#xff08;如 Chrome、Opera 和 Microsoft Edge&#xff09;中的工具&#xff0c;用于帮助开发人员调试和研究网站。 借助 Chrome DevTools&#xff0c;开发人员可以更深入地访问网站&#xf…...

前端技术栈es6+promise

let入门使用、 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>let 基本使用</title><script type"text/javascript">let name "hspedu教育";//老韩解读//1. conso…...

windows vscode使用opencv

1.windows vscode使用opencv 参考&#xff1a;https://blog.csdn.net/zhaiax672/article/details/88971248 https://zhuanlan.zhihu.com/p/402378383 https://blog.csdn.net/weixin_39488566/article/details/121297536 g -g .\hello_opencv.cpp -stdc14 -I E:\C-software\…...

json文件读取数据报错 AttributeError: ‘str‘ object has no attribute ‘items‘

trans_width_table表如下&#xff1a; {frozenset({2}): {3: 250, 2.5: 100, 1.5: 25, 2: 50, 1.8: 50, 2.75: 200, 5: 350, 4: 350, 2.3: 100, 4.5: 350, 3.5: 300}, frozenset({1, 3, 4, 5}): {2.5: 75, 2.75: 100, 1.5: 25, 4: 300, 3.5: 200, 4.5: 300, 3: 100, 5: 300, 2…...

1、Spring_IOC

IOC 1.概述 IOC&#xff1a;Inversion of Control 控制反转&#xff0c;可以让容器负责对象的创建以及销毁操作&#xff0c;对象在容器中叫 bean 2.回顾问题 问题&#xff1a;写了太多与业务无关的代码 耦合度非常高&#xff0c;写了很多和业务无关的代码不利于项目的升级迭…...

Socks5、IP代理在爬虫开发与HTTP通信中的应用

随着互联网的不断发展&#xff0c;代理服务器成为网络工程师和数据爬虫开发者的关键工具。本文将深入探讨Socks5代理、IP代理以及它们在网络安全、爬虫开发和HTTP通信中的重要作用。 1. 代理服务器&#xff1a;保障隐私与安全的中间人 代理服务器是位于客户端与目标服务器之间…...

重新认识小米

被镁光灯聚焦的企业&#xff0c;总是会被贴上各种标签。 8月14日&#xff0c;小米科技创始人雷军以“成长”为主题的年度演讲&#xff0c;刷遍社交网络。提到小米&#xff0c;你首先想到什么&#xff1f;手机发烧友、极致性价比&#xff0c;还是最年轻的500强&#xff1f; 这…...

react之react-redux的介绍、基本使用、获取状态、分发动作、数据流、reducer的分离与合并等

react之react-redux的介绍、基本使用、获取状态、分发动作、数据流、reducer的分离与合并等 一、react-redux介绍二、React-Redux-基本使用三、获取状态useSelector四、分发动作useDispatch五、 Redux 数据流六、代码结构七、ActionType的使用八、Reducer的分离与合并九、购物挣…...

滑块验证码-接口返回base64数据

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言所需包图片示例使用方法提示前言 滑动验证码在实际爬虫开发过程中会遇到很多,不同网站返回的数据也是千奇百怪。这里分享一种接口返回base64格式的情况以及处理方式 所需包 opencv-python、…...

智能文件改名,一键与上上级目录名称同步,让文件整理更加便捷

在整理文件时&#xff0c;经常会遇到需要将文件名称与上上级目录名称保持一致的情况。手动逐个修改文件名不仅费时费力&#xff0c;还容易出错。现在&#xff0c;我们为你带来了一款智能文件改名工具&#xff0c;让你能够一键将文件名称改成跟上上级目录名称一样&#xff0c;让…...

RK3399平台开发系列讲解(内核调试篇)Valgrind使用案例

🚀返回专栏总目录 文章目录 一、使用未初始化的内存案例二、内存泄露三、在内存被释放后进行读/写案例四、从已分配内存块的尾部进行读/写案例五、两次释放内存案例沉淀、分享、成长,让自己和他人都能有所收获!😄 📢Valgrind 是一个开源的内存调试和性能分析工具,用于…...

07_缓存预热缓存雪崩缓存击穿缓存穿透

缓存预热&缓存雪崩&缓存击穿&缓存穿透 一、缓存预热 提前将数据从数据库同步到redis。 在程序启动的时候&#xff0c;直接将数据刷新到redis懒加载&#xff0c;用户访问的时候&#xff0c;第一次查询数据库&#xff0c;然后将数据写入redis 二、缓存雪崩 发生情…...

常见前端基础面试题(HTML,CSS,JS)(三)

JS 中如何进行数据类型的转换&#xff1f; 类型转换可以分为两种&#xff0c;隐性转换和显性转换 显性转换 主要分为三大类&#xff1a;数值类型、字符串类型、布尔类型 三大类的原始类型值的转换规则我就不一一列举了 数值类型&#xff08;引用类型转换&#xff09; Numbe…...

CSS(JavaEE初阶系列14)

目录 前言&#xff1a; 1.CSS是什么 1.1CSS基本语法 2.引入样式 2.1内部样式表 2.2行内样式表 2.3外部样式 3.选择器 3.1选择器的种类 3.1.1基础选择器 3.1.2复合选择器 4.常用元素属性 4.1字体属性 4.2文本属性 4.3背景属性 4.4圆角矩形 4.5元素的显示模式 4…...

学习笔记230810--get请求的两种传参方式

问题描述 今天写了一个对象方式传参的get请求接口方法&#xff0c;发现没有载荷&#xff0c;ip地址也没有带查询字符串&#xff0c;数据也没有响应。 代码展示 错误分析 实际上这里的query是对象方式带参跳转的参数名&#xff0c;而get方法对象方式传参的参数名是parmas 解…...

游戏找不到msvcr100.dll解决方法,常见的三种解决方法

在计算机领域&#xff0c;msvcr100.dll是一个非常重要的动态链接库文件。它是Microsoft Visual C 2010 Redistributable的一部分&#xff0c;用于支持Visual Studio 2010的开发环境。然而&#xff0c;在某些情况下&#xff0c;msvcr100.dll可能会出现问题&#xff0c;导致程序无…...

机器学习知识点总结:什么是GBDT(梯度提升树)

什么是GBDT(梯度提升树) 虽然GBDT同样由许多决策树组成&#xff0c;但它与随机森林由许多不同。 其中之一是GBDT中的树都是回归树&#xff0c;树有分类有回归&#xff0c;区分它们的方法很简单。将苹果单纯分为好与坏的是分类树&#xff0c;如果能为苹果的好坏程度打个分&…...

SpringBoot + Vue 微人事权限组管理模块 (十四)

权限组前端页面制作 权限组管理角色和菜单之间关系&#xff0c;操作员管理着用户和角色之间的关系。 英文的输入框要有个前缀&#xff0c;SpringSecurity里角色英文名需要加一个ROLE_的前缀 上代码 <div><div class"permissManaTool"><el-input pla…...

Liunx系统编程:进程信号的概念及产生方式

目录 一. 进程信号概述 1.1 生活中的信号 1.2 进程信号 1.3 信号的查看 二. 信号发送的本质 三. 信号产生的四种方式 3.1 按键产生信号 3.2 通过系统接口发送信号 3.2.1 kill -- 向指定进程发送信号 3.2.2 raise -- 当自身发送信号 3.2.3 abort -- 向自身发送进程终止…...

宝塔端口监听不到端口

场景&#xff1a; 两个服务器同时在安装nginx 出问题导致20011没有在监听&#xff0c;重新删除nginx 就行了 当时一直以为是安全组没有放过端口&#xff0c;其实是没有监听 排查问题 php -S 0.0.0.0:端口 如果可以访问说明链接可以到服务器只是nginx没监听 sudo netstat …...

机器学习入门的概念

导航 一、 人工智能&#xff0c;机器学习&#xff0c;深度学习和传统学习二、数学基础三、编程语言 如果你刚刚入门机器学习&#xff0c;会接触到了非常多的概念。比如人工智能&#xff0c;机器学习&#xff0c;深度学习&#xff0c;神机网络&#xff0c;强化学习&#xff0c;各…...

插入排序优化——超越归并排序的超级算法

插入排序及优化 插入排序算法算法讲解数据模拟代码 优化思路一、二分查找二、copy函数 优化后代码算法的用途题目&#xff1a;数星星&#xff08;POJ2352 star&#xff09;输入输出格式输入格式&#xff1a;输出格式 输入输出样例输入样例输出样例 题目讲解步骤如下AC 代码 插入…...

面试之快速学习STL-容器适配器

1. 容器适配器 简单的理解容器适配器&#xff0c;其就是将不适用的序列式容器&#xff08;包括 vector、deque 和 list&#xff09;变得适用。 注意&#xff1a;默认使用的基础容器不代表一定只能用它&#xff0c;比如queue可以用deque&#xff0c;list。 如果你希望你的qu…...