【数据结构】队列(循环队列和链队列)详细讲解各种操作

news2025/1/20 5:52:46

🎊专栏【数据结构】

🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。

🎆音乐分享【勋章】

大一同学小吉,欢迎并且感谢大家指出我的问题🥰


图片来源网络,如果侵权,请联系我 

目录

⭐队列的分类 

✨循环队列

🎈优点

🎈缺点

✨链队列

🎈优点

🎈缺点

⭐基本概念

✨队列

✨队头

✨队尾

⭐循环队列  详细操作 

🎊定义

🎈算法步骤

🎈算法描述

🎆为什么要“循环”

🚥队空

🚥队满

🎊初始化

🎈算法步骤

🎈算法描述

🎊求队列长度

🎈算法步骤

🎈算法描述

🎊入队

🎈算法步骤

🎈算法描述

🎊出队

🎈算法步骤

🎈算法描述

🎊取队头元素

🎈算法步骤

🎈算法描述

🎊遍历队列

🎈算法步骤

🎈算法描述

🍔完整代码

⭐链队列  详细操作

🎊定义

🎊初始化

🎈算法步骤

🎈算法描述

🎊入队

🎈算法步骤

🎈算法描述

🎊出队

🎈算法步骤

🎈算法描述

🎊取队头元素

🎈算法步骤

🎈算法描述

🎊遍历队列

🎈算法步骤

🎈算法描述

🍔完整代码

😎附加题

🚥核心代码


⭐队列的分类 

✨循环队列

🎈优点

  1. 有效利用存储空间:因为循环队列可以重复使用已经出队的空间,所以相对于普通队列,它更能有效地利用存储空间。

  2. 提高队列操作效率:由于循环队列的队尾和队头可以相连,所以插入和删除元素的操作都可以在 O(1) 的时间内完成,使得队列操作效率提高。

  3. 方便实现算法:循环队列广泛应用于各种算法中,如 BFS(广度优先搜索)、模拟程序、操作系统等。这是因为循环队列具有较好的随机读取性能,方便实现算法。

🎈缺点

  1. 队列长度固定:循环队列的队列长度是固定的,无法动态扩容或缩小。如果队列长度过小,可能会导致入队操作失败,而队列长度过大则会浪费存储空间。

  2. 难以判断队列是否为空:由于循环队列的队头和队尾可以相连,因此当队头指针和队尾指针重合时,无法判断队列是空还是满。为了解决这个问题,通常需要在循环队列中增加一个计数器,记录队列中元素的个数。

  3. 不易实现动态删除操作:循环队列的底层存储结构通常采用数组实现,如果要删除队列中的某个元素,需要将该元素之后的所有元素依次前移,并将队尾指针重新指向前一个位置。这个操作比较繁琐,不如链式队列方便。

✨链队列

🎈优点

  1. 队列长度没有限制:链队列没有固定长度的限制,可以动态添加和删除队列中的元素,满足不同场景下的需求。

  2. 插入和删除操作方便:由于链队列是采用链式存储结构实现的,因此在插入和删除操作时,只需要改变指针的引用即可,而不必像顺序队列那样进行元素的搬移操作。

  3. 存储空间使用灵活:链队列只需要在堆上动态分配内存,因此它可以更灵活地使用存储空间,可以通过释放已经不再需要的节点来减少存储空间的浪费。

  4. 难以出现队列满的情况:链队列不会出现队列满的情况,因为它可以动态增长,只要内存允许,就可以无限添加元素。

🎈缺点

  1. 空间开销:在使用链式存储结构时,每个节点需要额外的空间来存储指向下一个节点的指针,因此链队列的空间开销相对于顺序队列要大。

  2. 难以实现随机访问:由于链队列的存储方式是链式的,因此在进行随机访问时,查找某个位置的节点需要从头节点开始依次遍历,效率比顺序队列低。

  3. 无法利用CPU缓存:链队列中每个节点的存储空间不连续,因此使用CPU缓存会出现严重缓存不命中问题,导致效率降低。

综上所述,链队列适合插入、删除操作频繁,而对于需要快速随机访问的场景则不是很适合。当然,数据结构的选择需要综合考虑业务需求和实际情况,选择最适合的数据结构。

⭐基本概念

✨队列

一种先进先出的线性表,只允许在表的一端进行插入,另一端进行删除,类似于平时日常生活的排队

✨队头

允许删除的一端是队头(别搞反了)

✨队尾

允许插入的一端的队尾(别搞反了)

⭐循环队列  详细操作 

🎊定义

🎈算法步骤

1.使用一组地址连续的存储单元依次存放从队头到队尾的元素

2.定义头指针front  尾指针rear

🎈算法描述

typedef struct SqQueue
{
	int *base;
	int front;//头指针
	int rear;//尾指针	
}SqQueue;

🎆为什么要“循环”

初始化创建空队列时,令front = rear = 0 ,

每当插入新的队尾元素时,尾指针rear+1,

每当删除队头元素时,头指针front+1

因此,头指针始终指向队头元素,尾指针始终指向队尾元素的下一个位置

如图所示

 

假设当前队列分配的最大空间为6,那么当队列在上图(d)状态时,就不能再继续插入新的队尾元素,否则会出现溢出现象(数组非法越界),但是现在队列实际可用的空间还没有占满,那么这种现象就被叫做“假溢出

变成“循环队列”就可以解决这个问题

循环队列里面,头,尾指针以及队列元素之间的关系不变,但是头,尾指针“按照环状+1”的操作可以通过“模”运算来实现。通过取模,头指针和尾指针就可以在顺序表空间里面以头尾衔接的方式“循环”移动

这样子

🚥队空

S.front==S.rear

🚥队满

(S.rear+1)%MAXSIZE==S.front

🎊初始化

初始化就是动态分配一个预定义大小为MAXSIZE的数组空间

🎈算法步骤

1.分配一个预定义大小为MAXSIZE的数组空间,base指向数组空间的首地址

2.将头指针和为指针置为0,表示空队列

🎈算法描述

int init(SqQueue &S)
{
	S.base=new int[maxsize];
	if(!S.base) return -1;
	S.front=S.rear=0;//空队列
	return 1;
}

🎊求队列长度

🎈算法步骤

对于非循环队列,尾指针和头指针的差值就是队列长度,但是对于循环队列,这样子算出的长度可能为负数,所以得把差值加上maxsize,然后与maxsize求余

🎈算法描述

int QueueLength(SqQueue S)
{
	return (S.rear-S.front+maxsize)%maxsize;
}

🎊入队

队尾插入一个新的元素

🎈算法步骤

1.判断队列是否满,如果满,返回-1

2.将新元素插入队尾

S.base[S.rear]=num

3.队尾指针+1

🎈算法描述

int EnQueue(SqQueue &S,int num)
{
	if((S.rear+1)%maxsize==S.front) return -1;
	S.base[S.rear]=num;
	S.rear=(S.rear+1)%maxsize;//入  队尾指针+1
	return 1;
}

🎊出队

删除队头元素

🎈算法步骤

1.判断队列是否满,如果满,返回-1

2.保存队头元素

3.队头指针+1

🎈算法描述

int DeQueue(SqQueue &S)
{
	if(S.front==S.rear) return -1;
	cout<<S.base[S.front]<<endl;
	S.front=(S.front+1)%maxsize;//出  队头指针+1
	return 1;	
}

🎊取队头元素

🎈算法步骤

当队列非空时,取出队头元素的值,队头指针不变

🎈算法描述

int GetHead(SqQueue S)
{
    if(S.front!=S.rear)    //非空
        return S.base[S.front];
}

🎊遍历队列

🎈算法步骤

1.判断队列是否空,如果空,返回-1

2.头指针+1,向下遍历队列

🎈算法描述

int Trance(SqQueue &S)
{
	if(S.front==S.rear) return -1;
	while(S.rear!=S.front)
	{
		cout<<S.base[S.front]<<" ";
		S.front=(S.front+1)%maxsize ;
	}
	return 1;
}

🍔完整代码

#include<iostream>
using namespace std;

typedef struct SqQueue
{
	int *base;
	int front;//头指针
	int rear;//尾指针	
}SqQueue;

#define maxsize 16

//1
int init(SqQueue &S)
{
	S.base=new int[maxsize];
	if(!S.base) return -1;
	S.front=S.rear=0;
	return 1;
}
//3
int EnQueue(SqQueue &S,int num)
{
	if((S.rear+1)%maxsize==S.front) return -1;
	S.base[S.rear]=num;
	S.rear=(S.rear+1)%maxsize;//入  队尾指针+1
	return 1;
}
//4
int DeQueue(SqQueue &S)
{
	if(S.front==S.rear) return -1;
	cout<<S.base[S.front]<<endl;
	S.front=(S.front+1)%maxsize;//出  队头指针+1
	return 1;	
}
//6
int Trance(SqQueue &S)
{
	if(S.front==S.rear) return -1;
	while(S.rear!=S.front)
	{
		cout<<S.base[S.front]<<" ";
		S.front=(S.front+1)%maxsize ;
	}
	return 1;
}
//7
int QueueLength(SqQueue S)
{
	return (S.rear-S.front+maxsize)%maxsize;
}

int main()
{
	SqQueue S;
	int n,m;
	cout<<"请选择:"<<endl;
	cout<<"1.初始化"<<endl;
	cout<<"2.队列是否空"<<endl;
	cout<<"3.入队"<<endl;
	cout<<"4.出队"<<endl;
	cout<<"5.判断队列是否满"<<endl;
	cout<<"6.遍历队列"<<endl;
	cout<<"7.求队列长度"<<endl;
	cout<<"0.结束"<<endl;
	for(;;)
	{
		int num;
		cin>>num;
		switch(num)
		{
			case 1:
				if(init(S)) cout<<"初始化成功"<<endl;
				else cout<<"初始化失败"<<endl;
				break;
			case 2:
				if(S.front==S.rear) cout<<"空队列"<<endl;
				else cout<<"非空队列"<<endl;
				break;
			case 3:
				cout<<"请输入需要入队的数目"<<endl;
				cin>>n;
				for(int i=0;i<n;i++)
				{
					cin>>m;
					if(EnQueue(S,m)) cout<<"入队成功"<<endl;
					else cout<<"入队失败"<<endl;
				}
				break;
			case 4:
				if(DeQueue(S)) cout<<"出队成功"<<endl;
				else cout<<"出队失败"<<endl;
				break;
			case 5:
				if(S.front==(S.rear+1)%maxsize) cout<<"队列已满"<<endl;
				else cout<<"队列未满"<<endl;
				break;
			case 6:
				if(Trance(S)) cout<<"遍历成功"<<endl;
				else cout<<"遍历失败"<<endl;
				break;
			case 7:
				cout<<"队列长度为:"<<QueueLength(S)<<endl;
			case 0:
				return 0;		
		}
	}
}

⭐链队列  详细操作

🎊定义

通常,链队列使用单链表来表示

这里为了操作方便,在队头前面加上一个头结点,并且令头指针始终指向头结点 

typedef struct QNode{
	int data;
	struct QNode *next;
}QNode,*QueuePtr;

typedef struct{
	QueuePtr front;
	QueuePtr rear;
}LinkQueue;

🎊初始化

初始化就是构造一个只有头结点的空队列

🎈算法步骤

1.生成新结点作为头结点,🏳️‍🌈队头和队尾指针都指向这个结点🏳️‍🌈

2.头结点的指针域置空

🎈算法描述

int init(LinkQueue &S)
{
	S.front=S.rear=new QNode;
	S.front->next=NULL;
	return 1;
}

🎊入队

尾插法 

与循环队列入队不同,链队列入队不用判断队是否满,只要为入队元素动态分配一个内存空间即可

🎈算法步骤

1.为入队元素分配一个内存空间,用指针p指向

2.将新结点的数据域置为e

3.将新结点插入到队尾

4.修改队尾指针为p

 

🎈算法描述

int EnQueue(LinkQueue &S,int e)
{
	QNode *P;//注意是*P 不是 P
	P=new QNode;
	P->data=e;
	
	P->next=NULL;
	
	S.rear->next=P;//插入队尾
	S.rear=P;//修改队尾指针
	return 1;
}

🎊出队

输出队头元素

出队前要判断队是否为空,出队后要释放队头元素的空间

🎈算法步骤

1.判断队列是否为空,如果为空,那么返回-1

2.临时保存队头元素的值,方便释放空间

3.修改头指针的指针域,方便指向下一个结点

4.判断出队元素是否为最后一个结点,如果是,那么就将队尾指针重新赋值,指向头结点

5.释放原队头元素的空间

🏳️‍🌈注意:S.front->next为队头,S.front不为队头🏳️‍🌈

🎈算法描述

需要判断当队列中的最后一个元素被删后,队尾指针也会丢失,因此要对队尾指针重新赋值(指向头结点)

int DeQueue(LinkQueue &S)
{
	QNode *P;
	if(S.front==S.rear) return -1;
	
	P=S.front->next;//p指向队头元素
	cout<<P->data<<endl;
	
	S.front->next=P->next;//修改头结点的指针域
	
	if(S.rear==P) S.rear=S.front;//如果最后一个元素被删,队尾指针指向头结点
	delete P;
	
	return 1;
}

🎊取队头元素

🎈算法步骤

1.判断队是否为空

2.输出队头元素

(S.front->next->data,不是S.front->data)

🎈算法描述

int GetHead(LinkQueue S)
{
    if(S.front!=S.rear)    //非空
        return S.front->next->data;
}

🎊遍历队列

🎈算法步骤

1.创建新结点P

2.新结点P指向队头S.front->next

3.从队头遍历到队尾

🎈算法描述

int Trance(LinkQueue &S)
{
	QNode *P;
	
	if(S.front==S.rear) return -1;
	P=S.front->next;
	while(P)
	{
		cout<<P->data<<" ";
		P=P->next;
	}
	return 1;
}

🍔完整代码

#include<iostream>
using namespace std;

#define maxsize 16

typedef struct QNode{
	int data;
	struct QNode *next;
}QNode,*QueuePtr;

typedef struct{
	QueuePtr front;
	QueuePtr rear;
}LinkQueue;

//1
int init(LinkQueue &S)
{
	S.front=S.rear=new QNode;
	S.front->next=NULL;
	return 1;
}
//3
int EnQueue(LinkQueue &S,int e)
{
	QNode *P;//注意是*P 不是 P
	P=new QNode;
	P->data=e;
	
	P->next=NULL;
	
	S.rear->next=P;//插入队尾
	S.rear=P;//修改队尾指针
	return 1;
}
//4
int DeQueue(LinkQueue &S)
{
	QNode *P;
	if(S.front==S.rear) return -1;
	
	P=S.front->next;//p指向队头元素
	cout<<P->data<<endl;
	
	S.front->next=P->next;//修改头结点的指针域
	
	if(S.rear==P) S.rear=S.front;//如果最后一个元素被删,队尾指针指向头结点
	delete P;
	
	return 1;
}
//5
int Trance(LinkQueue &S)
{
	QNode *P;
	
	if(S.front==S.rear) return -1;
	P=S.front->next;
	while(P)
	{
		cout<<P->data<<" ";
		P=P->next;
	}
	return 1;
}
int main()
{
	LinkQueue S;
	int n,m;
	cout<<"请选择:"<<endl;
	cout<<"1.初始化"<<endl;
	cout<<"2.队列是否空"<<endl;
	cout<<"3.入队"<<endl;
	cout<<"4.出队"<<endl;
	cout<<"5.遍历队列"<<endl;
	cout<<"0.结束"<<endl;
	for(;;)
	{
		int num;
		cin>>num;
		switch(num)
		{
			case 1:
				if(init(S)) cout<<"初始化成功"<<endl;
				else cout<<"初始化失败"<<endl;
				break;
			case 2:
				if(S.front==S.rear) cout<<"空队列"<<endl;
				else cout<<"非空队列"<<endl;
				break;
			case 3:
				cout<<"请输入需要入队的数目"<<endl;
				cin>>n;
				for(int i=0;i<n;i++)
				{
					cin>>m;
					if(EnQueue(S,m)) cout<<"入队成功"<<endl;
					else cout<<"入队失败"<<endl;
				}
				break;
			case 4:
				if(DeQueue(S)) cout<<"出队成功"<<endl;
				else cout<<"出队失败"<<endl;
				break;
			case 5:
				if(Trance(S)) cout<<"遍历成功"<<endl;
				else cout<<"遍历失败"<<endl;
				break;
			case 0:
				return 0;
		}
	}
}

😎附加题

        假设以数组Q[m]存放循环队列中的元素,同时设置一个标志tag,以tag= 0 和tag= 1来区别在队头指针(front)和队尾指针(rear)相等时,队列状态为“空” 还是“满"。

试编写与此结构相应的插入(Enqueue) 和删除(Dequeue) 算法。

🚥核心代码

#define m 10                                    // 定义循环队列的长度
int Q[m];                                       // 循环队列数组
int front = 0, rear = 0;                        // 队头指针和队尾指针
int tag = 0;                                    // 标志位,用于区分队空和队满状态

void Enqueue(int x) {                           // 插入元素到队尾
    if ((rear + 1) % m == front && tag == 0) {   // 判断队满
        cout << "队列已满" << endl;
        return;
    }
    Q[rear] = x;                                // 插入元素到队尾
    rear = (rear + 1) % m;                      // 队尾指针加1
    tag = 0;                                    // 标志为0表示队列不为空
}

int Dequeue() {                                 // 删除队头元素
    if (front == rear && tag == 1) {            // 判断队空
        cout << "队列已空" << endl;
        return -1;
    }
    int x = Q[front];                           // 取出队头元素
    front = (front + 1) % m;                    // 队头指针加1
    tag = 1;                                    // 标志为1表示队列不为满
    return x;
}

🥰如果大家有不明白的地方,或者文章有问题,欢迎大家在评论区讨论,指正🥰 

Code over! 

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

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

相关文章

爱智EdgerOS之深入解析离线下载任务

一、需求分析 在日常使用计算机的过程中&#xff0c;看到喜欢的资源不可避免地想把它下载到我们的设备上保存下来&#xff0c;比如图片&#xff0c;音视频资源&#xff0c;文档资源等&#xff0c;基于这种应用场景&#xff0c;现在来看看在爱智设备上可以如何实现呢&#xff1…

日撸 Java 三百行day33

文章目录 说明day33 图的广度优先遍历1.思路2.多个连通分量2 代码实现 说明 闵老师的文章链接&#xff1a; 日撸 Java 三百行&#xff08;总述&#xff09;_minfanphd的博客-CSDN博客 自己也把手敲的代码放在了github上维护&#xff1a;https://github.com/fulisha-ok/sampled…

82.qt qml-2D粒子系统、粒子方向、粒子项(一)

由于粒子系统相关的类比较多, 所以本章参考自QmlBook in chinese的粒子章节配合学习: 由于QmlBook in chinese翻译过来的文字有些比较难理解,所以本章在它的基础上做些个人理解,建议学习的小伙伴最好配合QmlBook in chinese一起学习。 1.介绍 粒子模拟的核心是粒子系统(Partic…

ResNet残差网络

ResNet 目的 Resnet网络是为了解决深度网络中的退化问题&#xff0c;即网络层数越深时&#xff0c;在数据集上表现的性能却越差。 原理 ResNet的单元结构如下&#xff1a; 类似动态规划的选择性继承&#xff0c;同时会在训练过程中逐渐增大&#xff08;/缩小&#xff09;该…

数字图像基础【7】应用线性回归最小二乘法(矩阵版本)求解几何变换(仿射、透视)

这一章主要讲图像几何变换模型&#xff0c;可能很多同学会想几何变换还不简单嚒&#xff1f;平移缩放旋转。在传统的或者说在同一维度上的基础变换确实是这三个&#xff0c;但是今天学习的是2d图像转投到3d拼接的基础变换过程。总共包含五个变换——平移、刚性、相似、仿射、透…

尚融宝10-Excel数据批量导入

目录 一、数据字典 &#xff08;一&#xff09;、什么是数据字典 &#xff08;二&#xff09;、数据字典的设计 二、Excel数据批量导入 &#xff08;一&#xff09;后端接口 1、添加依赖 2、创建Excel实体类 3、创建监听器 4、Mapper层批量插入 5、Service层创建监听…

2023年,想要靠做软件测试获得高薪,我还有机会吗?

时间过得很快&#xff0c;一眨眼&#xff0c;马上就要进入2023年了&#xff0c;到了年底&#xff0c;最近后台不免又出现了经常被同学问道这几个问题&#xff1a;2023年还能转行软件测试吗&#xff1f;零基础转行可行吗&#xff1f; 本期小编就“2023年&#xff0c;入行软件测…

一文解决nltk安装问题ModuleNotFoundError: No module named ‘nltk‘,保姆级教程

目录 问题一&#xff1a;No module named ‘nltk‘ 问题二&#xff1a;Please use the NLTK Downloader to obtain the resource 下载科学上网工具 问题三&#xff1a;套娃报错 如果会科学上网&#xff0c;可以直接看问题三 问题一&#xff1a;No module named ‘nltk‘ Mo…

【微服务笔记16】微服务组件之Gateway服务网关基础环境搭建

这篇文章&#xff0c;主要介绍微服务组件之Gateway服务网关基础环境搭建。 目录 一、Gateway服务网关 1.1、什么是Gateway 1.2、Gateway基础环境搭建 &#xff08;1&#xff09;基础环境介绍 &#xff08;2&#xff09;引入依赖 &#xff08;3&#xff09;添加路由配置信…

软件测试工程师的进阶之旅

很多人对测试工程师都有一些刻板印象&#xff0c;比如觉得测试“入门门槛低&#xff0c;没有技术含量”、“对公司不重要”、“操作简单工作枯燥”“一百个开发&#xff0c;一个测试”等等。 会产生这种负面评论&#xff0c;是因为很多人对测试的了解&#xff0c;还停留在几年…

Lesson12 udptcp协议

netstat命令->查看网络状态 n 拒绝显示别名&#xff0c;能显示数字的全部转化成数字l 仅列出有在 Listen (监听) 的服務状态p 显示建立相关链接的程序名t (tcp)仅显示tcp相关选项u (udp)仅显示udp相关选项a (all)显示所有选项&#xff0c;默认不显示LISTEN相关 pidof命令-&…

SQL select详解(基于选课系统)

表详情&#xff1a; 学生表&#xff1a; 学院表&#xff1a; 学生选课记录表&#xff1a; 课程表&#xff1a; 教师表&#xff1a; 查询&#xff1a; 1. 查全表 -- 01. 查询所有学生的所有信息 -- 方法一&#xff1a;会更复杂&#xff0c;进行了两次查询&#xff0c;第一…

机器学习笔记之正则化(六)批标准化(BatchNormalization)

机器学习笔记之正则化——批标准化[Batch Normalization] 引言引子&#xff1a;梯度消失梯度消失的处理方式批标准化 ( Batch Normalization ) (\text{Batch Normalization}) (Batch Normalization)场景构建梯度信息比例不平衡批标准化对于梯度比例不平衡的处理方式 ICS \text{…

《抄送列表》:过滤次要文件,优先处理重要文件

目录 一、题目 二、思路 1、查找字符/字符串方法&#xff1a;str1.indexOf( ) 2、字符串截取方法&#xff1a;str1.substring( ) 三、代码 详细注释版&#xff1a; 简化注释版&#xff1a; 一、题目 题目&#xff1a;抄送列表 题目链接&#xff1a;抄送列表 …

Java[集合] Map 和 Set

哈喽&#xff0c;大家好~ 我是保护小周ღ&#xff0c;本期为大家带来的是 Java Map 和 Set 集合详细介绍了两个集合的概念及其常用方法&#xff0c;感兴趣的朋友可以来学习一下。更多精彩敬请期待&#xff1a;保护小周ღ *★,*:.☆(&#xffe3;▽&#xffe3;)/$:*.★* ‘ 一、…

JVM知识汇总

1、JVM架构图 2、Java编译器 Java编译器做的事情很简单&#xff0c;其实就是就是将Java的源文件转换为字节码文件。 1. 源文件存储的是高级语言的命令&#xff0c;JVM只认识"机器码"&#xff1b; 2. 因此将源文件转换为字节码文件&#xff0c;即是JVM看得懂的"…

Node.js—Buffer(缓冲器)

文章目录 1、概念2.、特点3、创建Buffer3.1 Buffer.alloc3.2 Buffer.allocUnsafe3.3 Buffer.from 4、操作Buffer4.1 Buffer 与字符串的转化4.2 Buffer 的读写 参考 1、概念 Buffer 是一个类似于数组的对象 &#xff0c;用于表示固定长度的字节序列。Buffer 本质是一段内存空间…

视觉学习(四) --- 基于yolov5进行数据集制作和模型训练

环境信息 Jetson Xavier NX&#xff1a;Jetpack 4.4.1 Ubuntu&#xff1a;18.04 CUDA: 10.2.89 OpenCV: 4.5.1 cuDNN&#xff1a;8.0.0.180一.yolov5 项目代码整体架构介绍 1. yolov5官网下载地址&#xff1a; GitHub: https://github.com/ultralytics/yolov5/tree/v5.0 2. …

单元测试中的独立运行

单元测试中的独立运行 单元测试是针对代码单元的独立测试。要测试代码单元&#xff0c;首先要其使能够独立运行。项目中的代码具有依赖关系&#xff0c;例如&#xff0c;一个源文件可能直接或间接包含大量头文件&#xff0c;并调用众多其他源文件的代码&#xff0c;抽取其中的一…

论文阅读:Unsupervised Manifold Linearizing and Clustering

Author: Tianjiao Ding, Shengbang Tong, Kwan Ho Ryan Chan, Xili Dai, Yi Ma, Benjamin D. Haeffele Abstract 在本文中&#xff0c;我们建议同时执行聚类并通过最大编码率降低来学习子空间联合表示。 对合成和现实数据集的实验表明&#xff0c;所提出的方法实现了与最先进的…