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

[数据结构进阶 C++] 二叉搜索树(BinarySearchTree)的模拟实现

在这里插入图片描述

文章目录

  • 1、二叉搜索树
    • 1.1 二叉搜索数的概念
    • 1.2 二叉搜索树的操作
      • 1.2.1 二叉搜索树的查找
      • 1.2.2 二叉搜索树的插入
      • 1.2.3 二叉搜索树的删除
  • 2、二叉搜索树的应用
    • 2.1 K模型
    • 2.2 KV模型
  • 3、二叉搜索树的性能分析
  • 4、K模型与KV模型完整代码
    • 4.1 二叉搜索树的模拟实现(K模型)
    • 4.2 KV模型的模拟实现

1、二叉搜索树

1.1 二叉搜索数的概念

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

  • 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
  • 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
  • 它的左右子树也分别为二叉搜索树
    我们先给出两个示例:
    在这里插入图片描述
    此二叉树就不是搜索二叉树,根据性质来看,每颗子树也是二叉搜索树,红圈圈起来的地方显然是违背了这个性质。
    在这里插入图片描述
    此搜索二叉树按性质来看是完全满足的,因此此二叉树就是二叉搜索树。

1.2 二叉搜索树的操作

二叉搜索树的操作包含,增删查,下面我们就来分别模拟实现这些接口。

1.2.1 二叉搜索树的查找

思路:
a、从根开始比较,查找,比根大则往右边走查找,比根小则往左边走查找。
b、最多查找高度次,走到到空,还没找到,这个值不存在。
查找比较好理解,这里就不画图了,直接开始写代码。
1.查找的非递归方法:

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

2.查找的递归方法:

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

在递归查找中,我们用户在使用的时候只需要填入要查找的数字,但是我们的查找接口需要两个参数,开始节点与查找数值,因此我们在 FindR 下再封装一层 _FindR 就可以实现了。

1.2.2 二叉搜索树的插入

二叉搜索树的插入思路:
a. 树为空,则直接新增节点,赋值给root指针
b. 树不空,按二叉搜索树性质查找插入位置,插入新节点
我们先来以图例演示一遍过程:
对下面这棵树插入一个值为11的节点
在这里插入图片描述

这里是成功插入的情况,具体过程是上面的图例,我们在梳理一遍:
1、首先,我们用两个结点指针 parent和cur ,cur不断寻找正确插入位置,parent不断记下来cur的父节点指针;
2、当 cur 找到正确位置之后,先 new 一个节点对象给 cur,此时 new 出来的对象只是给了 cur 这个指针变量,并没有链接起来;
3、判断要插入的位置是 parent 的左孩子还是右孩子,再将其链接到正确位置插入就算完成了。
失败情况:
因为是二叉搜索树,节点左子树的值全小于节点的值,右子树的值全大于节点的值,不存在相等的情况,因此当找到一个节点的值与要插入的值相等时,就是插入失败,此时返回false。
根据上面的图示以及过程的梳理我们来写非递归版本的代码:

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

insert接口我们只提供非递归版本的。

1.2.3 二叉搜索树的删除

首先查找元素是否在二叉搜索树中,如果不存在,则返回, 否则要删除的结点可能分下面四种情
况:
a. 要删除的结点无孩子结点
b. 要删除的结点只有左孩子结点
c. 要删除的结点只有右孩子结点
d. 要删除的结点有左、右孩子结点

看起来有待删除节点有4中情况,实际情况a可以与情况b或者c合并起来,因此真正的删除过程
如下:
情况b:删除该结点且使被删除节点的双亲结点指向被删除节点的左孩子结点–直接删除
情况c:删除该结点且使被删除节点的双亲结点指向被删除结点的右孩子结点–直接删除
情况d:在它的右子树中寻找中序下的第一个结点(关键码最小),用它的值填补到被删除节点
中,再来处理该结点的删除问题–替换法删除
1、删除节点没有左孩子

在这里插入图片描述

// 1、左为空
if (cur->_left == nullptr)
{if (cur == _root){_root = cur->_right;}if (parent->_left == cur){parent->_left = cur->_right;}else{parent->_right = cur->_right;}
}

2、删除节点没有右孩子
在这里插入图片描述

// 2、右为空
else if (cur->_right == nullptr)
{if (cur == _root){_root = cur->_left;}		if (parent->_left == cur){parent->_left = cur->_left}else{parent->_right = cur->_left;}
}

3、删除节点左右孩子都存在
在这里插入图片描述

// 3、左右都不为空
else
{Node* parent = cur;Node* subLeft = cur->_right;while (subLeft->_left){parent = subLeft;subLeft = subLeft->_left;}swap(cur->_key, subLeft->_key);if (subLeft == parent->_left)parent->_left = subLeft->_right;elseparent->_right = subLeft->_right;delete(subLeft);
}

整个删除接口合在一起的代码:

bool Erase(const K& key)
{Node* parent = nullptr;Node* cur = _root;while (cur){if (key > cur->_key){parnet = cur;cur = cur->_right}else if (key < cur->_key){parent = cur;cur = cur->_left;}else{// 1、左为空if (cur->_left == nullptr){if (cur == _root){_root = cur->_right;}if (parent->_left == cur){parent->_left = cur->_right;}else{parent->_right = cur->_right;}delete(cur);}// 2、右为空else if (cur->_right == nullptr){if (cur == _root){_root = cur->_left;}		if (parent->_left == cur){parent->_left = cur->_left}else{parent->_right = cur->_left;}delete(cur);}// 3、左右都不为空else{Node* parent = cur;Node* subLeft = cur->_right;while (subLeft->_left){parent = subLeft;subLeft = subLeft->_left;}swap(cur->_key, subLeft->_key);if (subLeft == parent->_left)parent->_left = subLeft->_right;elseparent->_right = subLeft->_right;delete(subLeft);}}}	
}

递归版本:
递归版本与非递归版本类似, 非递归版本中使用while循环来找key位置,递归就是不断调用自身来找key位置当找到后依然分三种情况来分析:左为空、右为空、左右都不为空。
递归版本中用引用来接受传来的root,因此不用考虑链接问题也就不存在判断删除位置是父节点的左还是右,直接修改root即可。
1、左为空/左右都为空:先记下要删除的节点,再修改root,最后释放删除的节点。 Node* del = root; root = root->_right; delete(del);
2、右为空:先记下要删除的节点,再修改root,最后释放删除的节点。Node* del = root; root = root->_left; delete(del);
3、左右都不为空:先找到右子树的最左节点(最小值),交换 root->_key与subLeft->_key, 右子树的最左节点一定是叶子节点,因此删除subLeft直接再去调用函数自身即可,即再来一次左右都为空(左为空)的删除。

bool EraseR(const K& key)
{return _EraseR(_root, key);
}
bool _EraseR(Node*& root, const K& key)
{if (root == nullptr)return false;if (root->_key < key){_EraseR(root->_right, key);}else if (root->_key > key){_EraseR(root->_left, key);}else{if (root->_left == nullptr){Node* del = root;root = root->_right;delete(del);// 必须释放,不释放会导致内存泄漏return true;}else if (root->_right == nullptr){Node* del = root;root = root->_left;delete(del);return true;}else{Node* subLeft = root->_right;while (subLeft->_left){subLeft = subLeft->_left;}swap(root->_key, subLeft->_key);return _EraseR(root->_right, key);}}
}

2、二叉搜索树的应用

2.1 K模型

K模型:K模型即只有key作为关键码,结构中只需要存储Key即可,关键码即为需要搜索到的值。
比如:给一个单词word,判断该单词是否拼写正确,具体方式如下:

  • 以词库中所有单词集合中的每个单词作为key,构建一棵二叉搜索树
  • 在二叉搜索树中检索该单词是否存在,存在则拼写正确,不存在则拼写错误。

2.2 KV模型

KV模型:每一个关键码key,都有与之对应的值Value,即<Key, Value>的键值对。 该种方式在现实生活中非常常见:
● 比如英汉词典就是英文与中文的对应关系,通过英文可以快速找到与其对应的中文,英文单词与其对应的中文<word, chinese>就构成一种键值对;
● 再比如统计单词次数,统计成功后,给定单词就可快速找到其出现的次数,单词与其出现次数就是<word, count>就构成一种键值对。

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

插入和删除操作都必须先查找,查找效率代表了二叉搜索树中各个操作的性能。
对有n个结点的二叉搜索树,若每个元素查找的概率相等,则二叉搜索树平均查找长度是结点在二叉搜索树的深度的函数,即结点越深,则比较次数越多。
但对于同一个关键码集合,如果各关键码插入的次序不同,可能得到不同结构的二叉搜索树:
在这里插入图片描述
最优情况下,二叉搜索树为完全二叉树(或者接近完全二叉树),其平均比较次数为:log_2 N
最差情况下,二叉搜索树退化为单支树(或者类似单支),其平均比较次数为:N

最差情况是退化为单支树,性能就变得很差了,因为后续我们将改进搜索二叉树的插入与删除,来实现平衡二叉搜索树,即AVL树与红黑树(RB树)。

4、K模型与KV模型完整代码

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

namespace key
{template <class K>struct BSTreeNode{BSTreeNode* _left;BSTreeNode* _right;K _key;BSTreeNode(const K& key):_left(nullptr), _right(nullptr), _key(key){}};template <class K>class BSTree{typedef BSTreeNode<K> Node;public: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);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 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{// 删除分情况讨论:// 1. 左为空(左右都为空);2. 右为空;3.左右都不为空if (cur->_left == nullptr)// 左为空{if (cur == _root)// 根节点是删除的节点情况_root = cur->_right;else{if (cur == parent->_left){parent->_left = cur->_right;}else{parent->_right = cur->_right;}}delete(cur);}else if (cur->_right == nullptr)// 右为空{if (cur == _root)// 根节点是删除的节点情况_root = cur->_left;else{if (cur == parent->_left){parent->_left = cur->_left;}else{parent->_right = cur->_left;}}delete(cur);}else// 左右都不为空{// 替换法,找左子树最大 / 右子树最小来替换curNode* parent = cur;Node* subLeft = cur->_right;while (subLeft->_left){parent = subLeft;subLeft = subLeft->_left;}swap(cur->_key, subLeft->_key);if (subLeft == parent->_left)parent->_left = subLeft->_right;else// 处理删除根节点的情况parent->_right = subLeft->_right;delete(subLeft);}return true;}}return false;}void InOrder(){_InOrder(_root);cout << endl;}//递归bool InsertR(const K& key){return _InsertR(_root, key);}bool FindR(const K& key){return _FindR(_root, key);}bool EraseR(const K& key){return _EraseR(_root, key);}// C++11BSTree() = default; // 强制编译器生成默认构造BSTree(const BSTree<K>& t){_root = Copy(t._root);}// 赋值重载,现代写法BSTree<K>& operator=(BSTree<K> t){swap(_root, t._root);return *this;}~BSTree(){Destroy(_root);}private:Node* Copy(Node* root){if (root == nullptr)return nullptr;Node* newRoot = new Node(root->_key);newRoot->_left = Copy(root->_left);newRoot->_right = Copy(root->_right);return newRoot;}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){_InsertR(root->_right, key);}else if (root->_key > key){_InsertR(root->_left, 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){_EraseR(root->_right, key);}else if (root->_key > key){_EraseR(root->_left, key);}else{if (root->_left == nullptr){Node* del = root;root = root->_right;delete(del);// 必须释放,不释放会导致内存泄漏return true;}else if (root->_right == nullptr){Node* del = root;root = root->_left;delete(del);return true;}else{Node* subLeft = root->_right;while (subLeft->_left){subLeft = subLeft->_left;}swap(root->_key, subLeft->_key);return _EraseR(root->_right, key);}}}void _InOrder(Node* root){if (root == nullptr)return;_InOrder(root->_left);cout << root->_key << " ";_InOrder(root->_right);}private:Node* _root = nullptr;};
};

4.2 KV模型的模拟实现

namespace kv
{template <class K, class V>struct BSTreeNode{BSTreeNode<K, V>* _left;BSTreeNode<K, V>* _right;K _key;V _val;BSTreeNode(const K& key, const V& val):_left(nullptr), _right(nullptr), _key(key), _val(val){}};template <class K, class V>class BSTree{typedef BSTreeNode<K, V> Node;public:bool Insert(const K& key, const V& val){if (_root == nullptr){_root = new Node(key, val);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, val);if (parent->_key < key){parent->_right = cur;}else{parent->_left = cur;}return true;}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 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{// 删除分情况讨论:// 1. 左为空(左右都为空);2. 右为空;3.左右都不为空if (cur->_left == nullptr)// 左为空{if (cur == _root)// 根节点是删除的节点情况_root = cur->_right;else{if (cur == parent->_left){parent->_left = cur->_right;}else{parent->_right = cur->_right;}}delete(cur);}else if (cur->_right == nullptr)// 右为空{if (cur == _root)// 根节点是删除的节点情况_root = cur->_left;else{if (cur == parent->_left){parent->_left = cur->_left;}else{parent->_right = cur->_left;}}delete(cur);}else// 左右都不为空{// 替换法,找左子树最大 / 右子树最小来替换curNode* parent = cur;Node* subLeft = cur->_right;while (subLeft->_left){parent = subLeft;subLeft = subLeft->_left;}swap(cur->_key, subLeft->_key);if (subLeft == parent->_left)parent->_left = subLeft->_right;else// 处理删除根节点的情况parent->_right = subLeft->_right;delete(subLeft);}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->_val << endl;_InOrder(root->_right);}private:Node* _root = nullptr;};
};

相关文章:

[数据结构进阶 C++] 二叉搜索树(BinarySearchTree)的模拟实现

文章目录 1、二叉搜索树1.1 二叉搜索数的概念1.2 二叉搜索树的操作1.2.1 二叉搜索树的查找1.2.2 二叉搜索树的插入1.2.3 二叉搜索树的删除 2、二叉搜索树的应用2.1 K模型2.2 KV模型 3、二叉搜索树的性能分析4、K模型与KV模型完整代码4.1 二叉搜索树的模拟实现&#xff08;K模型…...

PostGIS学习教程十四:更多的空间连接

PostGIS学习教程十四&#xff1a;更多的空间连接 在上一节中&#xff0c;我们看到了ST_Centroid(geometry)和ST_Union([geometry])函数&#xff0c;以及一些简单的示例。在本节中&#xff0c;我们将用它们做一些更详细的事情。 提示&#xff1a;写完文章后&#xff0c;目录可以…...

【爬虫软件】孔夫子二手书采集

项目演示 孔网爬取图书信息 目录结构 [ |-- api-ms-win-core-synch-l1-2-0.dll, |-- api-ms-win-core-sysinfo-l1-1-0.dll, |-- api-ms-win-core-timezone-l1-1-0.dll, |-- api-ms-win-core-util-l1-1-0.dll, |-- api-ms-win-crt-conio-l1-1-0.dll, |-- api…...

P8736 [蓝桥杯 2020 国 B] 游园安排

题目描述 L \mathrm{L} L 星球游乐园非常有趣&#xff0c;吸引着各个星球的游客前来游玩。小蓝是 L \mathrm{L} L 星球 游乐园的管理员。 为了更好的管理游乐园&#xff0c;游乐园要求所有的游客提前预约&#xff0c;小蓝能看到系统上所有预约游客的名字。每个游客的名字由一…...

初识Docker-什么是docker

Docker是一个快速交付应用、运行应用的技术 目录 一、Docker 二、运用场景 一、什么是Docker&#xff1f;它的作用是什么&#xff1f; Docker如何解决大型项目依赖关系复杂&#xff0c;不同组件依赖的兼容性问题? Docker允许开发中将应用、依赖、函数库、配置一起打包&…...

maven的pom.xml设置本地仓库

配置 在Maven项目中&#xff0c;您可以在pom.xml文件中配置本地仓库的路径。在pom.xml文件中&#xff0c;您可以添加以下配置来指定本地仓库的路径&#xff1a; <project>...<repositories><repository><id>local-repo</id><url>file://…...

Qt获取屏幕DPI缩放比

获取屏幕缩放比 网上很多代码是用 logicalDotsPerInch 除以 96 来获取屏幕缩放比&#xff1a; // Windows 除以 96&#xff0c;macOS 除以 72 qreal factor window->screen()->logicalDotsPerInch() / 96.0; 当使能了缩放适配后&#xff0c;logicalDotsPerInch 值就不…...

Spring MVC控制层框架

三、Spring MVC控制层框架 目录 一、SpringMVC简介和体验 1. 介绍2. 主要作用3. 核心组件和调用流程理解4. 快速体验 二、SpringMVC接收数据 1. 访问路径设置2. 接收参数&#xff08;重点&#xff09; 2.1 param 和 json参数比较2.2 param参数接收2.3 路径 参数接收2.4 json参…...

vmware安装银河麒麟V10高级服务器操作系统

vmware安装银河麒麟V10高级服务器操作系统 1、下载银河麒麟V10镜像2、VMware安装银河麒麟V10高级服务器操作系统2.1、新建虚拟机2.2、安装虚拟机 3、配置银河麒麟V10高级服务器操作系统3.1、安装vmware tools3.2、配置静态IP地址 和 dns3.3、查看磁盘分区3.4、查看系统版本 1、…...

掌握Jenknis基础概念

目录 任务&#xff08;Jobs&#xff09; 构建&#xff08;Builds&#xff09; 触发器&#xff08;Triggers&#xff09; 构建环境&#xff08;Build Environment&#xff09;&#xff1a; 插件&#xff08;Plugins&#xff09;&#xff1a; 参数化构建&#xff08;Paramet…...

AWS 知识二:AWS同一个VPC下的ubuntu实例通过ldapsearch命令查询目录用户信息

前言&#xff1a; 前提&#xff1a;需要完成我的AWS 知识一创建一个成功运行的目录。 主要两个重要&#xff1a;1.本地windows如何通过SSH的方式连接到Ubuntu实例 2.ldapsearch命令的构成 一 &#xff0c;启动一个新的Ubuntu实例 1.创建一个ubuntu实例 具体创建实例步骤我就不…...

Ubuntu 常用命令之 fdisk 命令用法介绍

&#x1f4d1;Linux/Ubuntu 常用命令归类整理 fdisk 是一个用于处理磁盘分区的命令行工具&#xff0c;它在 Linux 系统中广泛使用。fdisk 命令可以创建、删除、更改、复制和显示硬盘分区&#xff0c;以及更改硬盘的分区 ID。 fdisk 命令的常用参数如下 -l&#xff1a;列出所…...

论文中公式怎么降重 papergpt

大家好&#xff0c;今天来聊聊论文中公式怎么降重&#xff0c;希望能给大家提供一点参考。 以下是针对论文重复率高的情况&#xff0c;提供一些修改建议和技巧&#xff0c;可以借助此类工具&#xff1a; 论文中公式怎么降重 一、引言 在论文撰写过程中&#xff0c;公式是表达学…...

27. 过滤器

Filter(过滤器)简介 Filter 的基本功能是对 Servlet 容器调用 Servlet 的过程进行拦截&#xff0c;从而在 Servlet 进行响应处理的前后实现一些特殊的功能。在 Servlet API 中定义了三个接口类来开供开发人员编写 Filter 程序&#xff1a;Filter, FilterChain, FilterConfigFi…...

做一个wiki页面是体验HTML语义的好方法

HTML语义&#xff1a;如何运用语义类标签来呈现Wiki网页 在上一篇文章中&#xff0c;我花了大量的篇幅和你解释了正确使用语义类标签的好处和一些场景。那么&#xff0c;哪些场景适合用到语义类标签呢&#xff0c;又如何运用语义类标签呢&#xff1f; 不知道你还记不记得在大…...

金融CRM有用吗?金融行业CRM有哪些功能

市场形式波诡云谲&#xff0c;金融行业也面临着资源体系分散、竞争力后继不足、未知风险无法规避等问题。金融企业该如何解决这些问题&#xff0c;或许可以了解一下CRM管理系统&#xff0c;和其提供的金融行业CRM解决方案。 金融行业是银行业、保险业、信托业、证券业和租赁业…...

@XmlAccessorType+@XmlElement完美解决Java类到XML映射问题

前言&#xff1a; 最近项目在做静态代码扫描的时候&#xff0c;出现Java类中成员变量命名的问题&#xff0c;开头字母必须小写&#xff0c;但是这个类成员是对接其他公司的字段&#xff0c;对方提供的请求格式是XML&#xff0c;必须将Java类转化为XML的格式&#xff0c;而且这…...

软件渗透测试有哪些测试流程?权威安全测试报告的重要性

软件渗透测试也是安全测试的一种&#xff0c;是通过模拟恶意黑客的攻击方法&#xff0c;来评估计算机网络系统安全的一种评估方法。作为网络安全防范的一种新技术&#xff0c;对于网络安全组织具有实际应用价值。 一、软件渗透测试的过程   软件渗透测试的过程通常包括四个主…...

安防视频融合云平台/智慧监控平台EasyCVR如何添加验证码调用接口?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…...

浏览器输入一个url,它的解析过程

URL解析&#xff1a; 浏览器首先解析URL&#xff0c;提取其中的协议&#xff08;例如&#xff0c;HTTP、HTTPS&#xff09;、域名和路径等信息。这个过程被称为URL解析。 DNS解析&#xff1a; 浏览器会检查域名的IP地址是否已经缓存。如果没有缓存或者缓存已经过期&#xff0c;…...

第29节: Vue3 列表渲染

在UniApp中使用Vue3框架时&#xff0c;你可以使用列表渲染语法来动态地渲染一个列表。下面是一个示例&#xff0c;演示了如何在UniApp中使用Vue3框架使用列表渲染&#xff1a; <template> <view> <button click"addItem">Add Item</button&g…...

CloudPulse:一款针对AWS云环境的SSL证书搜索与分析引擎

关于CloudPulse CloudPulse是一款针对AWS云环境的SSL证书搜索与分析引擎&#xff0c;广大研究人员可以使用该工具简化并增强针对SSL证书数据的检索和分析过程。 在网络侦查阶段&#xff0c;我们往往需要收集与目标相关的信息&#xff0c;并为目标创建一个专用文档&#xff0c…...

【网络安全】学习Web安全必须知道的一本书

【文末送书】今天推荐一本网络安全领域优质书籍。 目录 正文实战案例1&#xff1a;使用Docker搭建LAMP环境实战案例2&#xff1a;使用Docker搭建LAMP环境文末送书 正文 学习Web安全离不开Web&#xff0c;那么&#xff0c;需要先来学习网站的搭建。搭建网站是每一个Web安全学习…...

千帆 AppBuilder 初体验,不仅解决解决了我筛选简历的痛苦,更是让提效10倍!

文章目录 &#x1f31f; 前言&#x1f31f; 什么是百度智能云千帆 AppBuilder&#x1f31f; 百度智能云千帆 AppBuilder 初体验&#x1f31f; 利用千帆AppBuilder搭建简历小助手&#x1f31f; 让人眼前一亮的神兵利器 - 超级助理 &#x1f31f; 前言 前两天朋友 三掌柜 去北京…...

Ubuntu 常用命令之 cal 命令用法介绍

&#x1f4d1;Linux/Ubuntu 常用命令归类整理 cal命令在Ubuntu系统下用于显示日历。它可以显示任何特定月份或整个年份的日历。 cal命令的参数如下 -1&#xff1a;只显示当前月份的日历。-3&#xff1a;显示前一个月、当前月和下一个月的日历。-s&#xff1a;指定日历的开始…...

项目中webpack优化配置(1)

项目中webpack优化配置 一. 开发效率&#xff0c; 体验 1. DLL&#xff08;开发过程中减少构建时间和增加应用程序的性能&#xff09; 使用 DllPlugin 进行分包&#xff0c;使用 DllReferencePlugin(索引链接) 对 manifest.json 引用&#xff0c;让一些基本不会改动的代码先…...

【Qt之Quick模块】5. QML基本类型及示例用法

QML格式 QML基本类型 在 QML 中&#xff0c;有以下基本类型&#xff1a; int&#xff1a;整数类型。 Rectangle {function myFunction() {// 输出 debug 信息console.log("11 " (11));}Component.onCompleted: {myFunction();} }结果&#xff1a; 2. real&…...

MySQL运维实战(1.2)安装部署:使用二进制安装部署

作者&#xff1a;俊达 引言 上一篇我们使用了RPM进行安装部署&#xff0c;这是一种安装快速、简化部署和管理过程、与操作系统提供的包管理工具紧密集成的部署方法。此外&#xff0c;当你需要更高的灵活性和自定义性&#xff0c;并且愿意承担一些额外的手动配置和管理工作&am…...

ChatGPT一周年:开源语言大模型的冲击

自2022年末发布后&#xff0c;ChatGPT给人工智能的研究和商业领域带来了巨大变革。通过有监督微调和人类反馈的强化学习&#xff0c;模型可以回答人类问题&#xff0c;并在广泛的任务范围内遵循指令。在获得这一成功之后&#xff0c;人们对LLM的兴趣不断增加&#xff0c;新的LL…...

C++ Qt开发:Charts绘图组件概述

Qt 是一个跨平台C图形界面开发库&#xff0c;利用Qt可以快速开发跨平台窗体应用程序&#xff0c;在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置&#xff0c;实现图形化开发极大的方便了开发效率&#xff0c;本章将重点介绍QCharts二维绘图组件的常用方法及灵活运用。 …...

做爰的最好看的视频的网站/女排联赛排名

1.选择控制面板----> 选择 程序 ————> 选择 打开或关闭windows功能2.此时回弹出一个对话框&#xff0c;将telnet客户端打上√注意&#xff1a;不要讲telnet服务端打上√转载于:https://blog.51cto.com/linux2585/1540136...

虚拟服务器建网站/网络推广平台哪家公司最好

MySQL WHILE和LOOP和REPEAT循环的用法区别 MySQL三种循环的区别 MySQL循环使用方法一、MySQL循环概述MySQL中有三种循环&#xff0c;分别是 WHILE , REPEAT , LOOP (据说还有 goto)&#xff0c;不可单独使用&#xff0c;主要用于 存储过程 PROCEDURE 和 函数 FUNCTION 中。二、…...

wordpress中文视频教程/有哪些免费网站可以发布广告

text-shadow文本阴影 微信小程序交流群&#xff1a;111733917 | 微信小程序从0基础到就业的课程&#xff1a;https://edu.csdn.net/topic/huangjuhua 基础用法 在 CSS3 中&#xff0c;text-shadow 属性向文本添加一个或多个阴影。该属性是逗号分隔的阴影列表&#xff0c;每个…...

联谊会总结网站建设对外宣传/国内新闻热点事件

坚持、冷静、忍耐 转载于:https://www.cnblogs.com/whxleem/archive/2005/05/16/156489.html...

新建站点/网络营销管理名词解释

curl下载地址&#xff1a;https://curl.haxx.se/download.html&#xff0c;拉到页面最底下&#xff0c;选择红色选中的那个CAB的进行下载&#xff0c;如下图所示&#xff1a; 下载完成后&#xff0c;解压。 解决windows控制台curl中文乱码问题 下载iconv&#xff0c;地址&#…...

阿里云虚拟主机怎么建立网站/免费个人网站模板

知己知彼才能百战不殆。要想回答好问题就要先思考面试官的提问的动机。 首先我们分析一下面试官为什么要问这个问题&#xff0c;通过这个问题的答案他希望能获取到什么信息&#xff0c;然后我们把他希望获取到信息表达出来就可以了。面试官通过这个问题主要想了解三个方面&…...