二叉搜索树 K模型 和 KV模型

news2024/11/18 7:43:48

🌻个人主页:路飞雪吖~

      ✨专栏:C/C++


目录

一、二叉搜索树(K模型)的模拟实现

🌟二叉搜索树的概念

🌟二叉搜索树的操作

🌠二叉搜索树的查找

🌠二叉搜索树的插入

🌠二叉搜索树的删除

🌠二叉搜索树的中序遍历 

二、二叉搜索树(KV模型)的模拟实现

三、二叉搜索树的应用场景

四、二叉搜索树的性能分析

五、模拟实现的代码


一、二叉搜索树(K模型)的模拟实现

🌟二叉搜索树的概念

二叉搜索树(BST,Binary Search Tree),也称二叉排序树或二叉查找树。

一颗二叉搜索树,可以为空;

如果不为空,满足以下性质:

• 非空左子树的所有键值小于其根节点的键值

• 非空右子树的所有键值大于其根节点的键值

• 左、右子树都是二叉搜索树

🌟二叉搜索树的操作

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

模拟实现的基本框架:

#pragma once
#include<iostream>
using namespace std;

template<class K>
struct BSTNode
{
	K _key;
	BSTNode<K>* _left;
	BSTNode<K>* _right;

	BSTNode(const K& key)
		:_key(key)
		,_left(nullptr)
		,_right(nullptr)
	{}
};

template<class K>
class BSTree
{
	typedef BSTNode<K> Node;
public:

private:
	Node* _root = nullptr;
};

BSTNode  搜索二叉树的节点不仅要存该节点的值,还要存左右节点的指针,因此把节点封装成一个节点类,以便对节点插入、删除、查找等进行操作。

• K _key;  节点的值
  BSTNode<K>* _left;  节点的左  
  BSTNode<K>* _right;  节点的右

• BSTNode(const K& key)  节点的初始化

BSTree  二叉搜索树的主体实现(查找、删除、插入)

• typedef BSTNode<K> Node;  对节点进行取别名

🌠二叉搜索树的查找

我们知道在搜索树二叉树中,左子树的节点小于根节点的值,根节点的值小于右子树的值,因此我们根据这个特性对搜索二叉树进行查找:

	//查找
	bool Find(const K& key)
	{
		Node* cur = _root;//从根开始查找
		while (cur)
		{
			if (cur->_key < key)//如果当前的值小于要查找的值,往当前值的右边去查找
			{
				cur = cur->_right;
			}
			else if (cur->_key > key)//如果当前的值大于要查找的值,往当前值的左边去查找
			{
				cur = cur->_left;
			}
			else
			{
				return true;//找到返回真
			}
		}
		return false;//没找到返回假
	}

• 从根开始比较,查找,比根大往右边查找,比根小往左边查找;

•  最多查找高度次,走到空,还没找到,说明这个值不存在。

🌠二叉搜索树的插入

//插入
bool Insert(const K& key)
{
	//1、树为空,直接新增节点,赋值给root指针
if (_root == nullptr)
	{
		_root = new Node(key);
		return true;
	}
}

• 树为空,直接新增节点,赋值给root指针;

		//树不为空,按二叉搜索树性质查找插入位置,插入新节点
		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;//插入已有的值返回false
			}
		}

 • 树不为空,按二叉搜索树性质查找插入的位置 ;

 • Node* parent = nullptr; 记录插入节点的前一个指针,方便插入时的操作;

 • 插入已有的值返回false,二叉搜索树中不能存相同的值。

		//找到位置,插入新节点
		cur = new Node(key);
		if (parent->_key < key)
		{
			parent->_right = cur;
		}
		else
		{
			parent->_left = cur;
		}

  • 找到位置,创建节点,并判断节点是插入在前一个节点的左边还是右边。

	//插入
	bool Insert(const K& key)
	{
		//1、树为空,直接新增节点,赋值给root指针
	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;//插入已有的值返回false
			}
		}
		//找到位置,插入新节点
		cur = new Node(key);
		if (parent->_key < key)
		{
			parent->_right = cur;
		}
		else
		{
			parent->_left = cur;
		}
		return true;//插入完成
	}

 

🌠二叉搜索树的删除

• 按照二叉搜索树的性质查找到要删除的的节点:

bool Erase(const K& key)
{
	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;
}

此时该如何进行删除呢?

被删除的节点有以下几种情况:

   • <1>被删除的节点无孩子节点

   • <2>被删除的节点只有左孩子节点

   • <3>被删除的节点只有右孩子节点

情况1、2、3可归为同一类情况,因为有无孩节点也是指向空;

//0-1个孩子的情况
if (cur->_left == nullptr)//被删除节点的左为空 
{
				//如果要删除的是没有左子树的 根节点,此时根节点是没有parent的 
				if (parent == nullptr)
				{
					_root = cur->_right;//直接让根节点指向右子树
				}
				else
				{
					//先判断我是父亲的左还是右
					if (parent->_left == cur)
					{
						parent->_left = cur->_right;//让父亲指向我的右
					}
					else
					{
						//我是父亲的右
						parent->_right = cur->_right;
					}
				}

				delete cur;//删除节点
				return true;
}
else if (cur->_right==nullptr)//被删除节点的右为空
{
				//如果要删除的是没有右子树的 根节点,此时根节点是没有parent的 
				if (parent == nullptr)
				{
					_root = cur->_left;//直接让根节点指向右子树
				}
				else
				{
					if (parent->_left == cur)
					{
						parent->_left = cur->_left;
					}
					else
					{
						parent->_right = cur->_left;
					}
				}

				delete cur;//删除节点
				return true;
}
else
{
				//2个孩子的情况
				//如何删除?
}

  • <4>被删除的节点只有左、右孩子节点

情况4为另一类情况,该解决办法有两种,

方法一:选择被删除节点的右子树的最小值作为替代节点;

方法二:选择被删除节点的左子树的最大值作为替代节点。

这里选择方法一:

else
{
				//2个孩子的情况
				//法一:找要删除节点的右子树的最小节点作为替代节点  
                //法二:找要删除节点的左子树的最大节点作为替代节点
				//找右子树的最小节点
				//Node* rightMinP = nullptr;//rightMinP为rightMin的父亲,方便删除rightMin节点
				Node* rightMinP = cur;//如果rightMinP为空,就不进入循环里面,就为空指针,所以直接指向cur
				Node* rightMin = cur->_right;
				while (rightMin->_left)
				{
					rightMinP = rightMin;
					rightMin = rightMin->_left;//一直往左找
				}
				cur->_key = rightMin->_key;//替代要删除的节点
				//rightMin不一定是rightMinP的左,也有可能是右(rightMinP = cur)
				if(rightMinP->_left == rightMin)
				    rightMinP->_left = rightMin->_right;
				else
					rightMinP->_right = rightMin->_right;

				delete rightMin;
				return true;
}

🌠二叉搜索树的中序遍历 

public:
	void InOrder()
	{
		_InOrder(_root);
		cout << endl;
	}
	
private:
	void _InOrder(Node* root)
	{
		if (root == nullptr)
		{
			return;
		}

		_InOrder(root->_left);
		cout << root->_key << " ";
		_InOrder(root->_right);
	}

二、二叉搜索树(KV模型)的模拟实现

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

KV的模型与K模型一样,只不过是多存了一个值 :

  • 在查找时,找到返回节点的值,找不到返回nullptr;

  • 在插入时,树为空,新建的节点要存value;

namespace Key
{
	template<class K>
	class BSTree
	{
		
	};
}

namespace KeyValue
{
	template<class K, class V>
	class BSTree
	{
		

	};
}

三、二叉搜索树的应用场景

K模型:门禁系统 / 判断英语单词是否拼写正确

KV模型:英汉词典 / 统计单词出现的次数

四、二叉搜索树的性能分析

• 插入和删除操作都必须先查找,查找效率代表了二叉搜索树中的各个操作性能。

• 对有n个结点的二叉搜索树,若每个元素查找的概率相等,则二叉搜索树平均查找长度是结点在二叉搜索树的深度的函数,即结点越深,则比较次数越多。


• 最优情况下,二叉搜索树为完全二叉树(或者接近完全二叉树),

  其平均比较次数为:O(log₂N)

• 最差情况下,二叉搜索树退化为单支树(或者类似单支),其平均比较次数为:O(N)

五、模拟实现的代码

#pragma once
#include<iostream>
using namespace std;

namespace Key
{
	template<class K>
	struct BSTNode
	{
		K _key;
		BSTNode<K>* _left;
		BSTNode<K>* _right;


		BSTNode(const K& key)
			:_key(key)
			, _left(nullptr)
			, _right(nullptr)
		{}
	};

	template<class K>
	class BSTree
	{
		typedef BSTNode<K> Node;
	public:
		BSTree()
			:_root(nullptr)
		{}

		bool Insert(const K& key)
		{
			//树为空,直接新增节点,赋值给root指针
			if (_root == nullptr)
			{
				_root = new Node(key);
			}

			//树不为空,按二叉搜索树的性质查找插入位置,插入新节点
			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);
			if (parent->_key < key)
			{
				parent->_right = cur;
			}
			else
			{
				parent->_left = cur;
			}
			return true;
		}

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

		bool Erase(const K& key)
		{
			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
				{
					//找到节点删除
					//0-1个孩子
					if (cur->_left == nullptr)
					{
						if (parent == nullptr)
						{
							_root = cur->_right;
						}
						else
						{
							if (parent->_left == cur)
							{
								parent->_left = cur->_right;
							}
							else
							{
								parent->_right = cur->_right;
							}
						}
						delete cur;
						return true;
					}
					else if (cur->_right == nullptr)
					{
						if (parent == nullptr)
						{
							_root = cur->_left;
						}
						else
						{
							if (parent->_left = cur)
							{
								parent->_left = cur->_left;
							}
							else
							{
								parent->_right = cur->_left;
							}
						}
						delete cur;
						return true;
					}
					else
					{
						//有2个孩子的删除
						//找出该节点 右子树的最小节点
						Node* rightMinP = cur;
						Node* rightMin = cur->_right;
						while (rightMin->_left)
						{
							rightMinP = rightMin;
							rightMin = rightMin->_left;
						}
						cur->_key = rightMin->_key;

						if (rightMinP->_left == rightMin)
							rightMinP->_left = rightMin->_right;
						else
							rightMinP->_right = rightMin->_right;

						delete rightMin;
						return true;
					}
				}
			}

			//找不到节点
			return false;
		}

		void InOrder()
		{
			_InOrder(_root);
			cout << endl;
		}

	private:
		void _InOrder(Node* root)
		{
			if (root == nullptr)
			{
				return;
			}
			_InOrder(root->_left);
			cout << root->_key << " ";
			_InOrder(root->_right);
		}

	private:
		Node* _root = nullptr;
	};
}

namespace KeyValue
{
	template<class K, class V>//+
	struct BSTNode
	{
		K _key;
		V _value;//+
		BSTNode<K, V>* _left;
		BSTNode<K, V>* _right;

		BSTNode(const K& key, const V& value)//+
			:_key(key)
			,_value(value)//+
			, _left(nullptr)
			, _right(nullptr)
		{}
	};

	template<class K, class V>//+
	class BSTree
	{
		typedef BSTNode<K, V> Node;//+
	public:
		BSTree()
			:_root(nullptr)
		{}

		Node* Find(const K& key)//+返回节点指针
		{
			Node* cur = _root;
			while (cur)
			{
				if (cur->_key < key)
				{
					cur = cur->_right;
				}
				else if (cur->_key > key)
				{
					cur = cur->_left;
				}
				else
				{
					return cur;//+ 返回节点的指针
				}
			}
			return nullptr;//+ 没找到返回空
		}

		bool Insert(const K& key, const V& value)//+
		{
			if (_root == nullptr)
			{
				_root = new Node(key, value);//+
				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, value);//+
			if (parent->_key < key)
			{
				parent->_right = cur;
			}
			else
			{
				parent->_left = cur;
			}

			return true;

		}

		bool Erase(const K& key)
		{
			//元素是否在二叉搜索树上
			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
				{
					//找到节点,进行删除
					// 0-1 个孩子
					if (cur->_left == nullptr)
					{
						if (parent == nullptr)
						{
							_root = cur->_right;
						}
						else
						{
							if (parent->_left == cur)
							{
								parent->_left = cur->_right;
							}
							else
							{
								parent->_right = cur->_right;
							}
						}

						delete cur;
						return true;
					}
					else if (cur->_right == nullptr)
					{
						if (parent == nullptr)
						{
							_root = cur->_left;
						}
						else
						{
							if (parent->_left == cur)
							{
								parent->_left = cur->_left;
							}
							else
							{
								parent->_right = cur->_left;
							}
						}
						delete cur;
						return true;
					}
					else
					{
						// 删除有两个孩子的节点
						//找被删除节点的 右子树的最小值
						Node* rightMinP = cur;
						Node* rightMin = cur->_right;
						while (rightMin->_left)
						{
							rightMinP = rightMin;
							rightMin = rightMin->_left;
						}
						cur->_key = rightMin->_key;

						if (rightMinP->_left == rightMin)
							rightMinP->_left = rightMin->_right;
						else
							rightMinP->_right = rightMin->_right;

						delete rightMin;
						return true;
					}

				}
			}
			return false;
		}

		void InOrder()
		{
			_InOrder(_root);
			cout << endl;
		}

	private:
		void _InOrder(Node* root)
		{
			if (root == nullptr)
			{
				return;
			}
			_InOrder(root->_left);
			cout << root->_key << ":" << root->_value << endl;;
			_InOrder(root->_right);
		}

	private:
		Node* _root = nullptr;
	};
}
#include"SearchBinaryTree.h"
#include<string>

//int main()
//{
//	int a[] = { 8, 3, 1, 10, 6, 4, 7, 14, 13 };
//	//int a[] = { 8, 3, 3, 1, 3, 10, 6, 3, 4, 7, 5, 14, 13 };
//
//	BSTree<int> t;
//	for (auto e : a)
//	{
//		t.Insert(e);
//	}
//
//	//t.InOrder();
//
//	t.Find(100);
//
//	//t.Erase(4);
//	//t.InOrder();
//
//	//t.Erase(3);
//	//t.InOrder();
//
//	for (auto e : a)
//	{
//		t.Erase(e);
//		t.InOrder();
//	}
//
//	return 0;
//}


int main()
{
	KeyValue::BSTree<string, string> dic;
	dic.Insert("left", "左边");
	dic.Insert("right", "右边");
	dic.Insert("string", "字符串");
	dic.Insert("insert", "插入");

	string str;
	while (cin >> str)//string的流提取  ctrl+^Z +enter杀掉进程
	{
		//auto ret = dic.Find(str);
		KeyValue::BSTNode<string, string>* ret = dic.Find(str);
		if (ret)
		{
			cout << "->" << ret->_value << endl;
		}
		else
		{
			cout << "无此单词,请重新输入!!!" << endl;
		}
	}

	return 0;
}

int main()
{
	// 统计水果出现的次数
	string arr[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜",
   "苹果", "香蕉", "苹果", "香蕉" };
	KeyValue::BSTree<string, int> countTree;
	for (const auto& str : arr)
	{
		// 先查找水果在不在搜索树中
		// 1、不在,说明水果第一次出现,则插入<水果, 1>
		// 2、在,则查找到的节点中水果对应的次数++
		//BSTreeNode<string, int>* ret = countTree.Find(str);
		auto ret = countTree.Find(str);
		if (ret == NULL)
		{
			countTree.Insert(str, 1);
		}
		else
		{
			ret->_value++;
		}
	}
	countTree.InOrder();

	return 0;
}

如若对你有帮助,记得点赞、收藏、关注哦!

若有误,望各位,在评论区留言或者私信我 指点迷津!!!谢谢^ ^ ~

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

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

相关文章

Docker安装与应用

前言 Docker 是一个开源的应用容器引擎&#xff0c;基于 Go 语言开发。Docker 可以让开发者打包他们的应用以及依赖包到一个轻 量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。容器是完全使用沙箱机制&#xff0c;相互 之间…

《程序猿之Redis缓存实战(1) · 基础知识》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

OpenGL ES 绘制一个三角形(2)

OpenGL ES 绘制一个三角形(2) 简述 本节我们基于Android系统&#xff0c;使用OpenGL ES来实现绘制一个三角形。在OpenGL ES里&#xff0c;三角形是一个基础图形&#xff0c;其他的图形都可以使用三角形拼接而成&#xff0c;所以我们就的案例就基于这个开始。 在Android系统中…

添加vscode插件C/C++ snippets,快速生成LVGL .c/.h文件模版

文章目录 一、安装插件二、在安装目录下添加c.json和cpp.json文件①在 C:/Users/yourname/AppData/Roaming/Code/User/snippets/ 目录下创建 c.json 并填入如下内容&#xff1a;②在 C:/Users/yourname/AppData/Roaming/Code/User/snippets/ 目录下创建 cpp.json 并填入如下内容…

SQL学习1

24.9.28学习目录 一.数据库1.SQL语句基础2.匹配条件 一.数据库 对于嵌入式的数据库&#xff0c;其使用的是SQLite这种小型数据库&#xff1b; 在ubuntu中的下载方法 //字符界面 sudo apt-get install sqlite3//图形界面 sudo apt-get install sqlitemanSQLite特点&#xff1a…

windows系统中后台运行java程序

在windows系统中后台运行java程序&#xff0c;就是在启动java程序后&#xff0c;关闭命令行行窗口执行。 1、命令行方式 命令行方式运行java程序 启动脚本如下&#xff1a; echo off start java -jar app.jar exit启动后的结果如下 这种方式下&#xff0c;会马上启动一个命…

【RocketMQ】RocketMQ发送不同类型消息

&#x1f3af; 导读&#xff1a;本文介绍了RocketMQ消息队列系统中的几种消息发送模式及其应用场景&#xff0c;包括同步消息、异步消息以及事务消息。同步消息确保了消息的安全性&#xff0c;但牺牲了一定的性能&#xff1b;异步消息提高了响应速度&#xff0c;适用于对响应时…

搬砖6、Python函数和模块的使用

函数和模块的使用 在讲解本章节的内容之前&#xff0c;我们先来研究一道数学题&#xff0c;请说出下面的方程有多少组正整数解。 事实上&#xff0c;上面的问题等同于将8个苹果分成四组每组至少一个苹果有多少种方案。想到这一点问题的答案就呼之欲出了。 可以用Python的程序来…

人工智能开发实战照片智能搜索功能实现

内容提要 项目分析预备知识项目实战 一、项目分析 1、提出问题 随着人民生活水平的提高和手机照相功能的日趋完美&#xff0c;我们不经意中拍摄了很多值得回忆的时刻&#xff0c;一场说走就走的旅行途中也记录下许多令人心动的瞬间&#xff0c;不知不觉之中&#xff0c;我们…

Time-MoE : 时间序列领域的亿级规模混合专家基础模型

Time-MoE : 时间序列领域的亿级规模混合专家基础模型 时间序列预测一直是量化研究和工业应用中的重要课题。随着深度学习技术的发展&#xff0c;大规模预训练模型在自然语言处理和计算机视觉领域取得了显著进展&#xff0c;但在时间序列预测领域&#xff0c;这些模型的规模和运…

【归回预测】归回预测│PSO-ELM与标准ELM多输入预测对比源代码

摘要 本文比较了基于粒子群优化&#xff08;PSO&#xff09;和标准极限学习机&#xff08;ELM&#xff09;算法的电力负荷多输入预测模型。利用真实电力负荷数据集&#xff0c;对两种方法的预测性能进行了全面的评估&#xff0c;使用了均方误差&#xff08;MSE&#xff09;、平…

【文心智能体 | AI大师工坊】如何使用智能体插件,完成一款旅游类智能体的开发,来体验一下我的智能体『​​​​​​​厦门CityWalk』

目录 1.1、智能体运行效果 1.2、创作灵感来源 1.3、如何制作智能体 1.4、可能会遇到的几个问题 1.5、快速调优指南 『厦门CityWalk&#x1f680;』我的优质智能体&#xff1a;https://0nxj3k.smartapps.baidu.com/?_swebfr1&_swebScene3621000000000000 在当今这个全…

青动CRM V3.2.1

全面解决企业销售团队的全流程客户服务难题旨在助力企业销售全流程精细化、数字化管理&#xff0c;全面解决企业销售团队的全流程客户服务难题&#xff0c;帮助企业有效盘活客户资源、量化销售行为&#xff0c;合理配置资源、建立科学销售体系&#xff0c;提升销售业绩。标准授…

【宝藏妙招,轻松拿捏!】如何防止U盘资料被复制?U盘文件防拷贝的五种措施!

小李&#xff1a;“小张&#xff0c;你上次借我的U盘还回来的时候&#xff0c;我总觉得里面的资料好像被人动过了&#xff0c;有没有什么办法可以防止U盘里的资料被复制啊&#xff1f;” 小张&#xff1a;“当然有啦&#xff01;现在数据安全这么重要&#xff0c;防止U盘资料被…

贪心的思想

803.区间合并 给定 n 个区间 [li,ri]&#xff0c;要求合并所有有交集的区间。 注意如果在端点处相交&#xff0c;也算有交集。 输出合并完成后的区间个数。 例如&#xff1a;[1,3] 和 [2,6] 可以合并为一个区间 [1,6]。 输入格式 第一行包含整数 n。 接下来 n 行&#x…

如何通过GSR排名系统迅速提升谷歌排名?

如果你希望在谷歌上迅速提升某个关键词排名&#xff0c;或者某个关键词无论怎么优化都无法上首页&#xff0c;那么GSR关键词排名系统你就可以关注一下&#xff0c;GSR系统可以在短时间内帮助你进一步提升至首页。与传统的SEO方法不同&#xff0c;GSR侧重于外部优化&#xff0c;…

C语言进阶版第13课—字符函数和字符串函数2

文章目录 1. strstr函数的使用和模拟实现1.1 strstr函数的使用1.2 模拟实现strstr函数1.3 strstr函数和strncpy函数、puts函数的混合使用 2. strtok函数的使用**3. strerror函数的使用** 1. strstr函数的使用和模拟实现 1.1 strstr函数的使用 strstr函数是用来通过一个字符串来…

《迁移学习》—— 将 ResNet18 模型迁移到食物分类项目中

文章目录 一、迁移学习的简单介绍1.迁移学习是什么&#xff1f;2.迁移学习的步骤 二、数据集介绍三、代码实现1. 步骤2.所用到方法介绍的文章链接3. 完整代码 一、迁移学习的简单介绍 1.迁移学习是什么&#xff1f; 迁移学习是指利用已经训练好的模型&#xff0c;在新的任务上…

牛顿迭代法求解x 的平方根

牛顿迭代法是一种可以用来快速求解函数零点的方法。 为了叙述方便&#xff0c;我们用 C C C表示待求出平方根的那个整数。显然&#xff0c; C C C的平方根就是函数 f ( x ) x c − C f(x)x^c-C f(x)xc−C 的零点。 牛顿迭代法的本质是借助泰勒级数&#xff0c;从初始值开始快…

【软件测试】最新Linux大全(超详细!超级全!)

目录 前言1. 操作系统是干什么的2. Linux 是什么3. 为什么要学习 Linux4. Linux 发行版本5. Linux 系统特点6. Linux 安装7. Linux 系统启动8. Linux 操作方式9. Shell 与命令10. 命令格式 一、 Linux终端命令格式1. 终端命令格式2. 查阅命令帮助信息 二、 常用Linux命令的基本…