二叉搜索树的使用及其详细解析

1.概念

⼆叉搜索树⼜称⼆叉排序树,它或者是⼀棵空树,或者是具有以下性质的⼆叉树:

• 若它的左⼦树不为空,则左⼦树上所有结点的值都⼩于等于根结点的值

• 若它的右⼦树不为空,则右⼦树上所有结点的值都⼤于等于根结点的值

• 它的左右⼦树也分别为⼆叉搜索树

• ⼆叉搜索树中可以⽀持插⼊相等的值,也可以不⽀持插⼊相等的值,具体看使⽤场景定义,map/set/multimap/multiset系列容器底层就是⼆叉搜索树,其中map/set不⽀持插⼊相等值,multimap/multiset⽀持插⼊相等值 

 

2.性能分析

最优情况下,⼆叉搜索树为完全⼆叉树(或者接近完全⼆叉树),其⾼度为:O(logN)

最差情况下,⼆叉搜索树退化为单⽀树(或者类似单⽀),其⾼度为:O(N/2)

所以综合⽽⾔⼆叉搜索树增删查改时间复杂度为:O(N)

那么这样的效率显然是⽆法满⾜我们需求的,平衡⼆叉搜索树AVL树和红⿊树,才能适⽤于我们在内存中存储和搜索数据。

另外需要说明的是,⼆分查找也可以实现O(logN) 级别的查找效率,但是⼆分查找有两⼤缺陷: 1. 需要存储在⽀持下标随机访问的结构中,并且有序。 2. 插⼊和删除数据效率很低,因为存储在下标随机访问的结构中,插⼊和删除数据⼀般需要挪动数据。 这⾥也就体现出了平衡⼆叉搜索树的价值 

 

3.基本框架与基础功能

3.1基本框架

二叉搜索树的基本结构就是一个根节点加上左右子结点,在插入数据保证其左节点比根节点小,右节点比根节点大,当等于根节点则不插入,也可以额外设置一个树使其可以插入,其中需要注意的是拷贝构造函数需要显式实现使其成为深拷贝,并且在拷贝时顺序是前序拷贝,析构时则是后序析构,如果要显示二叉树,则使用中序遍历,这样可以保证显示的顺序由小到大,递增实现,相当于排序

//创建二叉搜索树
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;//using Node = BSTNode<K>;
public://使用公有成员函数调用私有可以避免实例化调用时无法使用私有成员变量的问题void InOrder(){_InOrder(_root);cout << endl;}//后序析构void Destroy(Node* root){if (root == nullptr){return;}Destroy(root->left);Destroy(root->right);delete root;}//析构函数无法传参,所以要独立创建一个函数析构~BSTree(){Destroy(_root);_root = nullptr;}Node* Copy(Node* root){if (root == nullptr){return nullptr;}//前序遍历拷贝树Node* newRoot = new Node(root->_key);Copy(newRoot->left);Copy(newRoot->right);return newRoot;}//拷贝构造BSTree(const BSTree& T){_root = Copy(T._root);}//强制生成默认构造函数BSTree() = default;//赋值重载BSTree& operator=(BTNode tmp){swap(_root, tmp._root);return *this;}private://中序遍历//此时中序遍历就满足了递增排序void _InOrder(Node* root){if (root == nullptr){return;}_InOrder(root->_left);cout << root->_key << ":" << root->_value << endl;_InOrder(root->_right);}Node* _root = nullptr;
};

3.2插入

1.当给出需要插入的数值,此时首先判断原来的二叉树是否为空,为空则直接插入头结点

2.若不为空则首先将该数值向下传递,按⼆叉搜索树性质,插⼊值⽐当前结点⼤往右⾛,插⼊值⽐当前结点⼩往左⾛,找到空位置,插⼊新结点

3.这时新创建一个节点,判断与此时的父节点的大小,大于父节点则插入到父节点的右边,反之插入到左边,相等则不插入

4.如果⽀持插⼊相等的值,插⼊值跟当前结点相等的值可以往右⾛,也可以往左⾛,找到空位置,插⼊新结点。(要注意的是要保持逻辑⼀致性,插⼊相等的值不要⼀会往右⾛,⼀会往左⾛)

bool Insert(const K& key)
{if (_root == nullptr){_root = new Node(key);return true;}Node* parent = nullptr;Node* cur = _root;while (cur){if (_root->_key < key){parent = cur;cur = cur->_right;}else if (_root->_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;
}

3.2查找

1. 从根开始⽐较,查找x,x⽐根的值⼤则往右边⾛查找,x⽐根值⼩则往左边⾛查找。

2. 最多查找⾼度次,⾛到到空,还没找到,这个值不存在。

3. 如果不⽀持插⼊相等的值,找到x即可返回

4. 如果⽀持插⼊相等的值,意味着有多个x存在,⼀般要求查找中序的第⼀个x

//查找
Node* Find(const K& key)
{Node* cur = _root;while (cur){if (cur->_key > key){cur = cur->_left;}else if (cur->_key < key){cur = cur->_right;}else{return cur;}}return nullptr;
}

3.3删除(重点)

⾸先查找元素是否在⼆叉搜索树中,如果不存在,则返回false

如果查找元素存在则分以下四种情况分别处理:(假设要删除的结点为N)

1. 要删除结点N左右孩⼦均为空

2. 要删除的结点N左孩⼦位空,右孩⼦结点不为空

3. 要删除的结点N右孩⼦位空,左孩⼦结点不为空

4. 要删除的结点N左右孩⼦结点均不为空

对应以上四种情况的解决⽅案:

1. 把N结点的⽗亲对应孩⼦指针指向空,直接删除N结点(情况1可以当成2或者3处理,效果是⼀样的)

2. 把N结点的⽗亲对应孩⼦指针指向N的右孩⼦,直接删除N结点

3. 把N结点的⽗亲对应孩⼦指针指向N的左孩⼦,直接删除N结点

4. ⽆法直接删除N结点,因为N的两个孩⼦⽆处安放,只能⽤替换法删除。找N左⼦树的值最⼤结点R(最右结点)或者N右⼦树的值最⼩结点R(最左结点)替代N,因为这两个结点中任意⼀个,放到N的位置,都满⾜⼆叉搜索树的规则。替代N的意思就是N和R的两个结点的值交换,转⽽变成删除R结点,R结点符合情况2或情况3,可以直接删除 

//删除
bool Erase(const K& key)
{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{//删除//1.左为空if (cur->_left == nullptr){//当需要删除根节点//需要特殊处理if (cur == _root){_root = cur->_right;}else{//当前节点为父节点的左节点//则将父节点的左指针指向被删除节点的左节点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;}else{//当前节点为父节点的左节点//则将父节点的左指针指向被删除节点的右节点if (parent->_left == cur){parent->_left = cur->_left;}//当前节点为父节点的右节点//则将父节点的右指针指向被删除节点的右节点else{parent->_right = cur->_left;}}delete cur;}else{//左右都不为空//此时需要寻找一个替代节点来保证不违反搜索二叉树的规则//还可以保证删除时步骤冗余//即左子树的最右节点或者右子树的最左节点都可以//右子树的最左节点Node* replaceParent = cur;Node* replace = cur->_right;while (cur->_left){//寻找右子树的最左节点replaceParent = replace;replace = replace->_left;}cur->_key = replace->_key;if (replaceParent->_left == replace){//replace的左节点一定为空,所以用他的父节点指向他的右节点replaceParent->_left = replace->_right;}else{replaceParent->_right = replace->_right;}delete replace;}return true;}}return false;
}

4.二叉搜索树的多种模型

4.1key模型

只有key作为关键码,结构中只需要存储key即可,关键码即为需要搜索到的值,搜索场景只需要判断 key在不在。key的搜索场景实现的⼆叉树搜索树⽀持增删查,但是不⽀持修改,修改key破坏搜索树结构了。

场景1:⼩区⽆⼈值守⻋库,⼩区⻋库买了⻋位的业主⻋才能进⼩区,那么物业会把买了⻋位的业主的⻋牌号录⼊后台系统,⻋辆进⼊时扫描⻋牌在不在系统中,在则抬杆,不在则提示⾮本⼩区⻋辆,⽆法进⼊

场景2:检查⼀篇英⽂⽂章单词拼写是否正确,将词库中所有单词放⼊⼆叉搜索树,读取⽂章中的单词,查找是否在⼆叉搜索树中,不在则波浪线标红提示

//key模型
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;//using Node = BSTNode<K>;public:bool Insert(const K& key){if (_root == nullptr){_root = new Node(key);return true;}Node* parent = nullptr;Node* cur = _root;while (cur){if (_root->_key < key){parent = cur;cur = cur->_right;}else if (_root->_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;}//使用公有成员函数调用私有可以避免实例化调用时无法使用私有成员变量的问题void InOrder(){_InOrder(_root);cout << endl;}//查找bool Find(const K& key){Node* cur = _root;while (cur){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->_right;}else if (cur->_key > key){parent = cur;cur = cur->_left;}else{//删除//1.左为空if (cur->_left == nullptr){//当需要删除根节点//需要特殊处理if (cur == _root){_root = cur->_right;}else{//当前节点为父节点的左节点//则将父节点的左指针指向被删除节点的左节点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;}else{//当前节点为父节点的左节点//则将父节点的左指针指向被删除节点的右节点if (parent->_left == cur){parent->_left = cur->_left;}//当前节点为父节点的右节点//则将父节点的右指针指向被删除节点的右节点else{parent->_right = cur->_left;}}delete cur;}else{//左右都不为空//此时需要寻找一个替代节点来保证不违反搜索二叉树的规则//还可以保证删除时步骤冗余//即左子树的最右节点或者右子树的最左节点都可以//右子树的最左节点Node* replaceParent = cur;Node* replace = cur->_right;while (cur->_left){//寻找右子树的最左节点replaceParent = replace;replace = replace->_left;}cur->_key = replace->_key;if (replaceParent->_left == replace){//replace的左节点一定为空,所以用他的父节点指向他的右节点replaceParent->_left = replace->_right;}else{replaceParent->_right = replace->_right;}delete replace;}return true;}}return false;}private://中序遍历//此时中序遍历就满足了递增排序void _InOrder(Node* root){if (root == nullptr){return;}_InOrder(root->_left);cout << root->_key << " ";_InOrder(root->_right);}private:Node* _root = nullptr;};
}

4.2key/value模型 

每⼀个关键码key,都有与之对应的值value,value可以任意类型对象。树的结构中(结点)除了需要存 储key还要存储对应的value,增/删/查还是以key为关键字⾛⼆叉搜索树的规则进⾏⽐较,可以快速查 找到key对应的value。key/value的搜索场景实现的⼆叉树搜索树⽀持修改,但是不⽀持修改key,修 改key破坏搜索树结构了,可以修改value

场景1:简单中英互译字典,树的结构中(结点)存储key(英⽂)和vlaue(中⽂),搜索时输⼊英⽂,则同时 查找到了英⽂对应的中⽂。

场景2:商场⽆⼈值守⻋库,⼊⼝进场时扫描⻋牌,记录⻋牌和⼊场时间,出⼝离场时,扫描⻋牌,查找⼊场时间,⽤当前时间-⼊场时间计算出停⻋时⻓,计算出停⻋费⽤,缴费后抬杆,⻋辆离场

场景3:统计⼀篇⽂章中单词出现的次数,读取⼀个单词,查找单词是否存在,不存在这个说明第⼀次 出现,(单词,1),单词存在,则++单词对应的次数 

//key_value模型
namespace key_val
{//创建二叉搜索树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;//using Node = BSTNode<K, V>;public://后序析构void Destroy(Node* root){if (root == nullptr){return;}Destroy(root->left);Destroy(root->right);delete root;}~BSTree(){Destroy(_root);_root = nullptr;}Node* Copy(Node* root){if (root == nullptr){return nullptr;}//前序遍历拷贝树Node* newRoot = new Node(root->_key, root->_value);Copy(newRoot->left);Copy(newRoot->right);return newRoot;}//拷贝构造BSTree(const BSTree& T){_root = Copy(T._root);}//强制生成默认构造函数BSTree() = default;//赋值重载BSTree& operator=(BTNode tmp){swap(_root, tmp._root);return *this;}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 (_root->_key < key){parent = cur;cur = cur->_right;}else if (_root->_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;}//使用公有成员函数调用私有可以避免实例化调用时无法使用私有成员变量的问题void InOrder(){_InOrder(_root);cout << endl;}//查找Node* Find(const K& key){Node* cur = _root;while (cur){if (cur->_key > key){cur = cur->_left;}else if (cur->_key < key){cur = cur->_right;}else{return cur;}}return nullptr;}//删除bool Erase(const K& key){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{//删除//1.左为空if (cur->_left == nullptr){//当需要删除根节点//需要特殊处理if (cur == _root){_root = cur->_right;}else{//当前节点为父节点的左节点//则将父节点的左指针指向被删除节点的左节点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;}else{//当前节点为父节点的左节点//则将父节点的左指针指向被删除节点的右节点if (parent->_left == cur){parent->_left = cur->_left;}//当前节点为父节点的右节点//则将父节点的右指针指向被删除节点的右节点else{parent->_right = cur->_left;}}delete cur;}else{//左右都不为空//此时需要寻找一个替代节点来保证不违反搜索二叉树的规则//还可以保证删除时步骤冗余//即左子树的最右节点或者右子树的最左节点都可以//右子树的最左节点Node* replaceParent = cur;Node* replace = cur->_right;while (cur->_left){//寻找右子树的最左节点replaceParent = replace;replace = replace->_left;}cur->_key = replace->_key;if (replaceParent->_left == replace){//replace的左节点一定为空,所以用他的父节点指向他的右节点replaceParent->_left = replace->_right;}else{replaceParent->_right = replace->_right;}delete replace;}return true;}}return false;}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;};
}

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

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

相关文章

JDK如何下载源码?

文章目录 JDK如何下载源码&#xff1f;JDK源码介绍下载JDK源码idea配置源码路径 JDK如何下载源码&#xff1f; JDK&#xff08;Java Development Kit&#xff09;是开发Java应用程序的基础工具包&#xff0c;包含了编译、运行和调试Java应用程序所需的所有工具。JDK源码主要指…

2024年中国研究生数学建模竞赛D题大数据驱动的地理综合问题

2024年中国研究生数学建模竞赛D题 大数据驱动的地理综合问题 地理系统是自然、人文多要素综合作用的复杂巨系统[1-2]&#xff0c;地理学家常用地理综合的方式对地理系统进行主导特征的表达[3]。如以三大阶梯概括中国的地形特征&#xff0c;以秦岭—淮河一线和其它地理区划的方…

2024华为杯研究生数学建模C题【数据驱动下磁性元件的磁芯损耗建模】思路详解

问题一 励磁波形分类 励磁波形作为影响磁芯性能的核心要素之一&#xff0c;其形态深刻影响着磁芯的损耗特性。励磁波形的独特形状直接塑造了磁芯内部磁通的动态行为&#xff0c;不同的波形轮廓影响了磁通密度随时间的变化速率&#xff0c;导致其损耗特性呈现出显著差异。因此&…

【操作系统】01.冯·诺伊曼体系结构

上面这张图就是我们经常能在各种教材中看到的冯诺伊曼体系结构。我们常见的计算机&#xff0c;如笔记本。我们不常见的计算机&#xff0c;如服务器&#xff0c;大部分都遵守冯诺依曼体系。 一、认识设备 输入设备&#xff1a; 键盘、鼠标、网卡、磁盘、摄像头…… 输出设备&a…

新峰商城之订单(一):确认页面开发

新峰商城订单从生成到处理结束&#xff0c;主要以下几个流程&#xff1a; &#xff08;1&#xff09;提交订单&#xff08;商城用户发起&#xff09; &#xff08;2&#xff09;订单入库&#xff08;后台逻辑&#xff09; &#xff08;3&#xff09;支付订单&#xff08;商城…

C++_多态

C_多态 多态的概念 通俗来讲&#xff0c;就是多种形态。多态分为编译时多态&#xff08;静态多态&#xff09;和运行时多态&#xff08;动态多态&#xff09;。 编译时多态主要就是函数重载和函数模板&#xff0c;他们传不同类型的参数就可以调用不同的函数&#xff0c;通过…

简单有效关于msvcp140.dll丢失的解决方法,msvcp140.dll

这篇文章将和大家分享几种msvcp140.dll丢失的解决方法&#xff0c;分析解决方法为什么能够通过这种方法进行修复成功&#xff0c;有效的将丢失的msvcp140.dll文件进行修复完成。 msvcp140.dll丢失&#xff1f;简单有效的解决途径 一、重新安装相关软件 原理 许多应用程序在安…

研究生数学建模竞赛E题思路模型参考文献高速公路应急车道紧急启用模型——高速公路饱和路段动态应急车道开放决策模型研究

1 概述 动态应急车道 ( Hard Shoulder Running ) 作为 调整路段交通流运行现状的重要管理手段&#xff0c; 可以在短时间内提供道路供给&#xff0c; 有效提升瓶颈路段的通行 能力。 早在 21 世纪初 &#xff0c; 欧美国家就已经通过开放 应急车道缓解的方式来解决路段的交…

2024最受人追捧的电脑远程控制软件推荐!首选这五款!好用、连接稳定、安全性高!

在2024年&#xff0c;电脑远程控制软件市场上涌现了众多受欢迎且功能强大的选择。 以下是根据最新信息推荐的五款好用、连接稳定、安全性高的电脑远程控制软件&#xff1a; 1. 安企神 特点&#xff1a;它是全球知名的远程控制软件&#xff0c;以其稳定性和可靠性著称。 它支…

C++——初步认识C++和namespace的用法

1.编程语言排行榜 我们通过排行可以看出 C在变成语言中还是占据着重要的地位 2.C在工作领域中的应用 1.PC客户端开发。⼀般是开发Windows上的桌面软件&#xff0c;比如WPS之类的&#xff0c;技术栈的话⼀般是C和 QT&#xff0c;QT 是⼀个跨平台的 C图形用户界面&#xff08;G…

sourceTree使用脚本一键push代码到gerrit

问题 在gerrit,我们无法直接把代码push到对应的分支。需要把代码push到 HEAD:refs/for/branch,review通过后再submit到分支。所以无法直接使用sourceTree上的推送按钮来push代码。但是可以通过自定义操作和脚本来实现这一功能。 脚本编写 新建文本文档写入以下内容&#xff…

fmql之ubuntu添加dhcp服务

按照官方指示&#xff1a;【在文末】 2024-08-22 buildroot linux 使用wpa_supplicant -B -i wlan0 切换WIFI 设备之后无法上网的问题。解决方法&#xff0c;使用udhcpc -i wlan0 命令-CSDN博客 网口连接路由器&#xff0c;然后发现路由器分配了ip&#xff0c;但是板卡没有配置…

VulnHub-Narak靶机笔记

Narak靶机笔记 概述 Narak是一台Vulnhub的靶机&#xff0c;其中有简单的tftp和webdav的利用&#xff0c;以及motd文件的一些知识 靶机地址&#xff1a; https://pan.baidu.com/s/1PbPrGJQHxsvGYrAN1k1New?pwda7kv 提取码: a7kv 当然你也可以去Vulnhub官网下载 一、nmap扫…

写作练习(一)

一、reply Z-Library The aim is to express gratitude and practice writing, and as a record. 二、Original letter As a college student of computer and a blogger, Z-Library is always a part of my study, which provide many books that I need pay a lost of time …

安捷伦Agilent/keysight 53220A参数资料 通用频率计 计数器

Agilent 53220A&#xff0c;Keysight 53220A&#xff0c;通用频率计数器/计时器&#xff0c;350 MHz&#xff0c;12 位&#xff0c;100 ps 53220A 350 MHz 通用频率计数器/计时器是一款双通道频率计数器&#xff0c;能够执行所需的全部频率和时间间隔测量。它可以添加可选的射…

突破常规:如何利用动态系统思维彻底变革你的团队!

引言 在现代社会中&#xff0c;变化是唯一不变的。面对快速发展的科技和瞬息万变的市场环境&#xff0c;企业和开发团队必须具备适应性和灵活性。动态系统思维作为一种理解和应对复杂系统中变化的方法&#xff0c;提供了有效的解决方案。本文将探讨动态系统思维在敏捷方法中的应…

load jsonl File with OpenAI API request results to pandas data.frame

题意&#xff1a;将包含 OpenAI API 请求结果的 jsonl 文件加载到 pandas DataFrame 中 问题背景&#xff1a; I have a large data set containing around 500k observation. It has a string variable that I want to create an embedding for. I used the OpenAI API to cr…

AI入门系列 | 如何优雅地下载最前沿的模型?

​简介 一片白云横谷口&#xff0c;几多归鸟尽迷巢。 小伙伴们好&#xff0c;我是微信公众号《小窗幽记机器学习》的小编&#xff1a;卖铁观音的小男孩。本系列主要基于过往经历&#xff0c;总结当时自身环境中实操经验。倘若能够顺便帮到他人&#xff0c;也是善莫大焉。 本文…

[已更新]2024数学建模研赛华为杯E题详细思路代码成品文章研究生数学建模数模辅导

截止2024.8.21 12点 已更新e全部小问的建模和问题一的代码 ####https://docs.qq.com/doc/DVU9YYUFLWlNOY3pyE题: 问题1&#xff1a;统计四个观测点的交通流参数随时间的变化规律 为了统计交通流参数&#xff08;如车流密度、流量和速度&#xff09;&#xff0c;首先需要从视…

猫咪检测系统源码分享

猫咪检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vision …