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

搜索二叉树【C++】

文章目录

  • 二叉搜索树
  • 二叉搜索树的模拟实现
  • 构造函数
  • 拷贝构造函数
  • 赋值运算符重载函数
  • 析构函数
  • Insert
    • 循环
    • 递归
  • Erase
    • 循环
    • 递归
  • Find
    • 循环
    • 递归
  • 二叉搜索树的应用
  • K模型
    • KV模型
  • 完整代码
    • 普通版本
    • 递归版本

二叉搜索树

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

若它的左子树不为空,
则左子树上所有结点的值都小于根结点的值。

若它的右子树不为空,
则右子树上所有结点的值都大于根结点的值。

它的左右子树也分别是二叉搜索树。

在这里插入图片描述

二叉搜索树的模拟实现

构造函数

	BSTree():_root(nullptr){}

拷贝构造函数

	BSTree(const  BSTree<K>& t)//BSTree(  BSTree<K>  *this ,  const  BSTree<K> & t)//t1 =t {_root = Copy(t._root);}private:Node* Copy(Node* root){if (root == nullptr){return nullptr;}Node* copyNode = new Node(root->_key);//递归 copyNode->_left = Copy(root->_left);copyNode->_right = Copy(root->_right);return  copyNode;}

赋值运算符重载函数

	//赋值重载 BSTree<K>& operator= (BSTree<K>& t)//t1 = t//深拷贝{swap(_root, t._root);return *this;}

析构函数

~BSTree(){Destroy(_root);}private:void Destroy(Node*& root) //引用的目的:将每个节点释放后同时置空{//后序遍历 if (root == nullptr){return;}Destroy(root->_left);Destroy(root->_right);delete root;root = nullptr;}

Insert

核心思路:

如果是空树,则直接将插入结点作为二叉搜索树的根结点。

如果不是空树,则按照二叉搜索树的性质进行结点的插入。
如果待插入结点的值<根结点的值,则需要将结点插入到左子树当中。
如果待插入结点的值>根结点的值,则需要将结点插入到右子树当中。
如果待插入结点的值等于根结点的值,则插入失败。

循环

bool Insert(const K & key ){//空树if (_root == nullptr){_root = new Node(key);return true;}//不是空树Node* parent = nullptr;//找到父节点Node* cur = _root;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);//不知道parent在那一边,需要进一步判断if (parent->_key > key){//parent在左边parent->_left = cur;}else if (parent->_key < key){//parent在右边parent->_right = cur;}else{return false;}return true;}

递归

	bool InsertR(const K& key)//递归版本{return _InsertR(_root, key);}private: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;}}

Erase

先找到需要删除的节点
需要删除的节点可能会有三种情况:
1、待删除结点的左子树为空(待删除结点的左右子树均为空包含在内)

在这里插入图片描述

2、待删除结点的右子树为空。
在这里插入图片描述

1、2 两种情况,被删除的节点都只有一个孩子

3、待删除结点的左右子树均不为空,即被删除节点有两个孩子
使用替换法处理第3中情况:
1、找替换节点:替换节点一般是左子树的最大节点(最右节点),或者是右子树的最小节点(最左节点)
2、将替换的节点删除

在这里插入图片描述
特殊情况:

在这里插入图片描述

循环

	bool Erase(const K& key){Node* parent = nullptr;//待删除节点的父节点Node* cur = _root;//待删除的节点//不是空树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;}//待删除节点不是根节点,并且此时parent不为nullptrelse{if (parent->_right == cur){parent->_right = cur->_right;}else//parent->_left ==cur{parent->_left = cur->_right;}}}//待删除节点的右子树为空 ,即一个孩子的情况else if (cur->_right == nullptr){//待删除节点是根节点if (cur == _root){//将根节点改为待删除节点的左孩子_root = cur->_left;}//待删除节点不是根节点,并且此时parent不为nullptrelse{if (parent->_right == cur){parent->_right = cur->_left;}else//parent->_left==cur{parent->_left = cur->_left;}}} else //待删除的节点的左右孩子都不为空 (替换法:左子树的最大节点即最右节点,或者右子树的最小节点即最左节点,并且将替换的节点删除){//替换法//找替代节点Node* parent = cur;//找左子树的最大节点,左子树的最大节点一定没有右孩子Node* leftMax = cur->_left;while (leftMax->_right){parent = leftMax; //记录leftMax的父节点,防止删除leftMax时找不到该节点位置 //一直往右子树找leftMax = leftMax->_right;}//左子树的最大节点和待删除节点替换swap(cur->_key, leftMax->_key);//重新改变链接关系//特殊情况 if (parent->_left == leftMax){parent->_left = leftMax->_left;}else//普通情况 parent->_right== leftMax{parent->_right = leftMax->_left;}cur = leftMax;}//删除左子树的最大节点delete cur;return true;}}return false;}

递归

	bool EraseR(Node* _root, const K& key)//递归版本{return _EraseR(_root, key);}private:bool _EraseR(Node*& root, const K& key)//引用的目的:不用找父节点,不需要用父节点比较大小{//结束条件if (root == nullptr){return false;}//往左树找if (root->_key > key){return _EraseR(root->_left, key);}//往右树找else if (root->_key < key){return _EraseR(root->_right, 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 (root->_left){root = root->_left;}//将左子树最大节点与被删除节点替换swap(leftMax->_key, root->_key);return _EraseR(root, key);}delete del;//?return true;}}

Find

循环

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

递归

	bool FindR(Node* _root, const K& key)//递归版本{return _FindR(_root, key);}private:bool  _FindR(Node* root, const K& key){//结束条件if (root == nullptr){return false;}if (root->_key > key){return _FindR(root->_left, key);}else if (root->_key < key){return _FindR(root->_right, key);}else{return true;}}

二叉搜索树的应用

K模型

K模型,即只有key作为关键码,结构中只需存储key即可,关键码即为需要搜索到的值。

比如:给定一个单词,判断该单词是否拼写正确。具体方式如下:

	void TestBSTree1(){BSTree<string, string > dict;dict.InsertR("insert", "插入");dict.InsertR("sort", "排序");dict.InsertR("right", "右边");dict.InsertR("date", "日期");string str;while (cin>>str){auto * ret  = dict.FindR(str);//auto ret = dict.FindR(str);if (ret){cout << ret->_value << endl;}else{cout << "无此单词" << endl;}}}

KV模型

KV模型,对于每一个关键码key,都有与之对应的值value,即<key, value>的键值对。

英汉词典就是英文与中文的对应关系,即<word, Chinese>就构成一种键值对。具体方式如下

1、以<单词, 中文含义>为键值对,构建一棵二叉搜索树。注意:二叉搜索树需要进行比较,键值对比较时只比较key。
2、查询英文单词时,只需给出英文单词就可以快速找到与其对应的中文含义。

完整代码

普通版本

#pragma once 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){}bool Insert(const K & key ){//空树if (_root == nullptr){_root = new Node(key);return true;}//不是空树Node* parent = nullptr;//找到父节点Node* cur = _root;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);//不知道parent在那一边,需要进一步判断if (parent->_key > key){//parent在左边parent->_left = cur;}else if (parent->_key < key){//parent在右边parent->_right = cur;}else{return false;}return true;}bool Find(const K & key){Node* cur = _root;while (cur){if (cur->_left > key){cur = cur->_left;}else if (cur->_left < key){cur = cur->_right;}else{return false;}return true;}}bool Erase(const K& key){Node* parent = nullptr;//待删除节点的父节点Node* cur = _root;//待删除的节点//不是空树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;}//待删除节点不是根节点,并且此时parent不为nullptrelse{if (parent->_right == cur){parent->_right = cur->_right;}else//parent->_left ==cur{parent->_left = cur->_right;}}}//待删除节点的右子树为空 ,即一个孩子的情况else if (cur->_right == nullptr){//待删除节点是根节点if (cur == _root){//将根节点改为待删除节点的左孩子_root = cur->_left;}//待删除节点不是根节点,并且此时parent不为nullptrelse{if (parent->_right == cur){parent->_right = cur->_left;}else//parent->_left==cur{parent->_left = cur->_left;}}} else //待删除的节点的左右孩子都不为空 (替换法:左子树的最大节点即最右节点,或者右子树的最小节点即最左节点,并且将替换的节点删除){//替换法//找替代节点Node* parent = cur;//找左子树的最大节点Node* leftMax = cur->_left;while (leftMax->_right){parent = leftMax; //记录leftMax的父节点,防止删除leftMax时找不到该节点位置 //一直往右子树找leftMax = leftMax->_right;}//左子树的最大节点和待删除节点替换swap(cur->_key, leftMax->_key);//重新改变链接关系//特殊情况 if (parent->_left == leftMax){parent->_left = leftMax->_left;}else//普通情况 {parent->_right = leftMax->_left;//parent->_right =nullptr;}cur = leftMax;}//删除左子树的最大节点delete cur;return true;}}return false;}//中序遍历void InOrder(){_InOrder(_root);cout << endl;}void _InOrder(Node *root  ){if (root == nullptr){return; }_InOrder(root->_left);cout << root->_key << " ";_InOrder(root->_right);}private:Node* _root;
};void TestBSTree1()
{int a[] = { 8, 3, 1, 10, 6, 4, 7, 14, 13 };BSTree<int> t;for (auto e : a){t.Insert(e);}t.InOrder();t.Erase(4);t.InOrder();t.Erase(6);t.InOrder();t.Erase(7);t.InOrder();t.Erase(3);t.InOrder();for (auto e : a){t.Erase(e);}t.InOrder();}

递归版本

#pragma once 
#include<string>
using namespace std;
namespace key
{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{public:typedef  BSTreeNode<K> Node;public:BSTree():_root(nullptr){}~BSTree(){Destroy(_root);}//拷贝构造BSTree(const  BSTree<K>& t)//BSTree(  BSTree<K>  *this ,  const  BSTree<K> & t)//t1 =t {_root = Copy(t._root);}//赋值重载 BSTree<K>& operator= (BSTree<K>& t)//t1 = t{swap(_root, t._root);return *this;}bool EraseR(Node* _root, const K& key)//递归版本{return _EraseR(_root, key);}bool InsertR(const K& key)//递归版本{return _InsertR(_root, key);}bool FindR(Node* _root, const K& key)//递归版本{return _FindR(_root, key);}private:Node* Copy(Node* root){if (root == nullptr){return nullptr;}Node* copyNode = new Node(root->_key);//递归 copyNode->_left = Copy(root->_left);copyNode->_right = Copy(root->_right);return  copyNode;}void Destroy(Node*& root) //引用的目的:将每个节点释放后同时置空{//后序遍历 if (root == nullptr){return;}Destroy(root->_left);Destroy(root->_right);delete root;root = nullptr;}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 _EraseR(Node*& root, const K& key)//引用的目的:不用找父节点,不需要用父节点比较大小{//结束条件if (root == nullptr){return false;}//往左树找if (root->_key > key){return _EraseR(root->_left, key);}//往右树找else if (root->_key < key){return _EraseR(root->_right, 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 (root->_left){root = root->_left;}//将左子树最大节点与被删除节点替换swap(leftMax->_key, root->_key);return _EraseR(root, key);}delete del;//?return true;}}bool  _FindR(Node* root, const K& key){//结束条件if (root == nullptr){return false;}if (root->_key > key){return _FindR(root->_left, key);}else if (root->_key < key){return _FindR(root->_right, key);}else{return true;}}public://中序遍历void InOrder(){_InOrder(_root);cout << endl;}void _InOrder(Node* root){if (root == nullptr){return;}_InOrder(root->_left);cout << root->_key << " ";_InOrder(root->_right);}public:Node* _root;};void TestBSTree1(){int a[] = { 8, 3, 1, 10, 6, 4, 7, 14, 13 };BSTree<int> t;for (auto e : a){t.InsertR(e);}t.InOrder();//没有引用,释放了,只是指针没有置空,尤其是根节点_root,我们还能通过他找到/*t.Destroy(t._root);*/t.EraseR(t._root, 4);t.InOrder();t.EraseR(t._root, 6);t.InOrder();t.EraseR(t._root, 7);t.InOrder();t.EraseR(t._root, 3);t.InOrder();for (auto e : a){t.EraseR(t._root, e);}t.InOrder();}void TestBSTree2(){int a[] = { 8, 3, 1, 10, 6, 4, 7, 14, 13 };BSTree<int> t;for (auto e : a){t.InsertR(e);}t.InOrder();BSTree<int> t1(t);t.InOrder();t1.InOrder();}
}namespace key_value
{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{public:typedef BSTreeNode<K, V> Node;public:BSTree():_root(nullptr){}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: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->_right){leftMax = leftMax->_right;}swap(root->_key, leftMax->_key);return _EraseR(root->_left, key);}delete del;return true;}}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->_right, key, value);}else if (root->_key > key){return _InsertR(root->_left, 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;}}void _InOrder(Node* root){if (root == NULL){return;}_InOrder(root->_left);cout << root->_key << ":" << root->_value << endl;_InOrder(root->_right);}private:Node* _root;};void TestBSTree1(){BSTree<string, string > dict;dict.InsertR("insert", "插入");dict.InsertR("sort", "排序");dict.InsertR("right", "右边");dict.InsertR("date", "日期");string str;while (cin>>str){auto * ret  = dict.FindR(str);//auto ret = dict.FindR(str);if (ret){cout << ret->_value << endl;}else{cout << "无此单词" << endl;}}}void TestBSTree2(){string arr[] = {"西瓜", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };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();}}

如果你觉得这篇文章对你有帮助,不妨动动手指给点赞收藏加转发,给鄃鳕一个大大的关注你们的每一次支持都将转化为我前进的动力!!!

相关文章:

搜索二叉树【C++】

文章目录 二叉搜索树二叉搜索树的模拟实现构造函数拷贝构造函数赋值运算符重载函数析构函数Insert循环递归 Erase循环递归 Find循环递归 二叉搜索树的应用K模型KV模型 完整代码普通版本递归版本 二叉搜索树 二叉搜索树又称为二叉排序树&#xff0c;它或者是一棵空树&#xff0…...

华为云云耀云服务器L实例评测|认识redis未授权访问漏洞 漏洞的部分复现 设置连接密码 redis其他命令学习

前言 最近华为云云耀云服务器L实例上新&#xff0c;也搞了一台来玩&#xff0c;期间遇到过MySQL数据库被攻击的情况&#xff0c;数据丢失&#xff0c;还好我有几份备份&#xff0c;没有造成太大的损失。昨天收到华为云的邮箱提醒&#xff0c;我的redis数据库没有设置密码&…...

快速安装NGINX

快速安装NGINX #安装依赖包 yum -y install gcc pcre pcre-devel zlib zlib-devel openssl openssl-devel#下载NGINX curl -O https://nginx.org/download/nginx-1.21.6.tar.gz#解压NGINX tar -zxvf nginx-1.21.6.tar.gz cd nginx-1.21.6.tar.gz#配置 ./configure --prefix/…...

一台电脑远程内网的另外一台电脑,禁止远程的电脑连接外网,只允许内网连接

一台电脑远程内网的另外一台电脑&#xff0c;禁止远程的电脑连接外网&#xff0c;只允许内网连接 1.找到右下角网卡图标&#xff0c;右键图标选择“打开网络和共享中心”。 3、点击“更改适配器设置”。 4、右键正在使用的网卡“本地连接”打开属性 5、找到“internet协…...

山西电力市场日前价格预测【2023-09-24】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-09-24&#xff09;山西电力市场全天平均日前电价为496.09元/MWh。其中&#xff0c;最高日前电价为705.54元/MWh&#xff0c;预计出现在14: 30。最低日前电价为333.70元/MWh&#xff0c;预计…...

MQ---第二篇

系列文章目录 文章目录 系列文章目录一、RabbitMQ事务消息二、RabbitMQ死信队列、延时队列一、RabbitMQ事务消息 通过对信道的设置实现 channel.txSelect();通知服务器开启事务模式;服务端会返回Tx.Select-Okchannel.basicPublish;发送消息,可以是多条,可以是消费消息提交…...

C++ 创建文件并写入内容

文章目录 1.问题2.filesystem3.示例参考文献 1.问题 C 如何向指定路径的文件写入内容呢&#xff1f; 这里有几点要求&#xff1a; 如果目录不存在需要自动创建。如果文件不存在需要自动创建。以覆盖的方式写入内容。 2.filesystem C17 带来了一个新的库&#xff1a;filesy…...

微信小程序rich-text里面写多行溢出显示省略号在ios中不显示的问题

问题&#xff1a;微信小程序rich-text里面写多行溢出显示省略号在ios中不显示的问题 解决方法&#xff1a;需要给一个默认的div标签&#xff0c;在div写行内样式 overflow : hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-o…...

解决Win11/10中Edge浏览器页面加载不出来、打不开问题|有网但是打不开,加载不了

问题症状 edge浏览器打不开&#xff0c;有网络能正常上网&#xff0c;但是edge浏览器无法浏览。网络质量很高&#xff0c;但是页面就是加载不出来&#xff0c;详情如下&#xff1a; &#xff08;我是在科学上网后造成这样子的原因&#xff0c;现在将我的方法分享一下&#xff…...

【DRAM存储器五】DRAM存储器的架构演进-part2

&#x1f449;个人主页&#xff1a;highman110 &#x1f449;作者简介&#xff1a;一名硬件工程师&#xff0c;持续学习&#xff0c;不断记录&#xff0c;保持思考&#xff0c;输出干货内容 参考书籍&#xff1a;《Memory Systems - Cache, DRAM, Disk》 目录 以提升吞吐…...

分享一个基于uniapp+springboot技术开发的校园失物招领小程序(源码、lw、调试)

&#x1f495;&#x1f495;作者&#xff1a;计算机源码社 &#x1f495;&#x1f495;个人简介&#xff1a;本人七年开发经验&#xff0c;擅长Java、Python、PHP、.NET、微信小程序、爬虫、大数据等&#xff0c;大家有这一块的问题可以一起交流&#xff01; &#x1f495;&…...

RabbitMQ工作模式——Routing路由模式

1.Routing路由模式 Routing生产者代码 public class Producer_Routing {public static void main(String[] args) throws IOException, TimeoutException {//1.创建连接工厂ConnectionFactory factory new ConnectionFactory();//2.设置参数factory.setHost("172.16.98.…...

Python字典的增删改查以及嵌套

嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 &#x1f447; &#x1f447; &#x1f447; 更多精彩机密、教程&#xff0c;尽在下方&#xff0c;赶紧点击了解吧~ python源码、视频教程、插件安装教程、资料我都准备好了&#xff0c;直接在文末名片自取就可 字典 基础数…...

【淘宝开店】新手入门开网店教程

一、上架产品流程顺序 1. 上架10个产品2. 早中晚各上架1件产品3. 连续上架4天 二、产品培训 动销率要求: 店铺产品数必须>10公式: 店铺最近30天有销量产品数 / 店铺上架总产品数 * 100%1. 从动销率可以得出, 店铺产品不宜过多2. 小卖家前期最佳建议产品数10个 三、上架产品…...

计网第五章(运输层)(五)(TCP拥塞控制)

目录 一、基本概念 二、拥塞控制算法 慢开始&#xff1a; 拥塞避免&#xff1a; 快重传&#xff1a; 快恢复&#xff1a; 一、基本概念 若对网络中某一资源的需求超过了该资源所能提供的可用部分&#xff08;供不应求&#xff09;&#xff0c;网络性能就会变坏。 在计算…...

windows/ubuntu怎么修改hosts文件

windows系统修改方法&#xff1a; 第一步&#xff1a;用管理员权限打开记事本&#xff0c;或者visual studio。 第二步&#xff1a;用记事本或者vs打开地址C:\Windows\System32\drivers\etc\hosts文件&#xff0c;这个时候就可以直接修改了 Ubuntu22 LTS系统修改方法&#xf…...

(日积月累版)大数据基础知识点1-关系型数据库

好久不见&#xff0c;甚是想念。 笔者最近有时间整理关于大数据的一些基础知识点&#xff0c;整理的目不在于能提升多少技能&#xff0c;关键在于巩固一些很基础的知识点&#xff0c;毕竟互联网就是基础略稳固的人比较有优势&#xff0c;在遇到或发现一些技术问题时&#xff0c…...

【开心消消乐】python实现-附ChatGPT解析

1.题目 开心消消乐 知识点编程基础:深搜、广搜 时间限制: 1s 空间限制: 256MB 限定语言:不限 题目描述: 给定一个N行M列的二维矩阵,矩阵中每个位置的数宁取值为0或1。矩阵示例如: 1 1 0 0 0 0 0 1 0 0 1 1 1 1 1 1 现需要将矩阵中所有的1进行反转为0,规则如下: 1)、当点击一…...

springBoot源码汇总

SpringFactoriesLoader 示例位置 SpringApplication#getSpringFactoriesInstances 加载spring.factroies下的初始化类 ClassLoader classLoader this.getClassLoader();Set<String> names new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoade…...

代码随想录二刷day39

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、力扣62. 不同路径二、力扣63. 不同路径 II 前言 一、力扣62. 不同路径 class Solution {public int uniquePaths(int m, int n) {int[][] dp new int[m][…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker &#xff1b;并安装。 基础操作不再赘述。 打开 macOS 终端&#xff0c;开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)

考察一般的三次多项式&#xff0c;以r为参数&#xff1a; p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]&#xff1b; 此多项式的根为&#xff1a; 尽管看起来这个多项式是特殊的&#xff0c;其实一般的三次多项式都是可以通过线性变换化为这个形式…...

STM32HAL库USART源代码解析及应用

STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...

2025年低延迟业务DDoS防护全攻略:高可用架构与实战方案

一、延迟敏感行业面临的DDoS攻击新挑战 2025年&#xff0c;金融交易、实时竞技游戏、工业物联网等低延迟业务成为DDoS攻击的首要目标。攻击呈现三大特征&#xff1a; AI驱动的自适应攻击&#xff1a;攻击流量模拟真实用户行为&#xff0c;差异率低至0.5%&#xff0c;传统规则引…...