数据结构(其三)--栈与队列

news2024/11/16 21:31:20

目录

5.栈

5.1 栈的基本操作

5.2 各种栈

(1).顺序栈

        i.普通顺序栈

        ii.共享栈

        iii.关于销毁

(2).链栈

6.队列

6.1 队列的基本操作

6.2 各种队列

(1).循环队列

        i.代码

        ii.另外一种写法

(2).链式队列

        i.代码

(3).双端队列

7.栈在括号匹配中的应用

       i.主要思路

       ii.代码

8.栈在表达式求值中的应用

       (1).中缀表达式

        (2).前缀表达式

        (3).后缀表达式

        i.中缀转后缀,

        ii.后缀的运算(手算)

        iii.中缀转前缀

        iiii.前缀的运算(手算)

        iiiii.中缀转后缀(机算)

9.栈在递归中的应用

10.队列的应用(以后会学到)


5.栈

        栈(Stack)是一种允许在一端进行插入和删除的线性表

        特点:先入栈的元素,后出栈。(LIFO:Lost in,First out)

        空栈:没有数据元素的栈。

        栈顶:允许进行插入与删除的一端。

        栈底:不可进行操作的一端,除非栈底也是栈顶。

        出栈序列的种类数:
        

        n 指栈中的元素个数

5.1 栈的基本操作

*

InitStack(&S):初始化栈,创造一个空栈,分配内存

DestoryStack(&S):销毁栈,释放栈占用的内存空间。

*

Push(&S, x):进栈,若S栈未满,则加入x 并使之成为新栈顶。——————————增

Pop(&S, &x):出栈,若S栈非空,则弹出栈顶元素,并将之返回。--------------------------删

*

GetTop(S, &x):读取栈顶元素,若S栈非空,则用x返回栈顶元素。(不删除元素)----查

*

StackEmpty(S):判断一个栈是否为空。为空,则返回true;反之,返回false.

5.2 各种栈

(1).顺序栈

        i.普通顺序栈

        顺序储存——数组

#define MaxSize 10	//
//顺序栈
class SqStack           //sequence stack
{
public:
	int data[MaxSize];	//静态数组存放栈元素
	int top;			//栈顶指针,储存栈顶的数组下标
};

//初始化
void InitStack(SqStack& S)
{
	S.top = -1;			//初始化栈顶指针
}
//判断栈是否为空
bool StackEmpty(SqStack S)
{
	if (S.top == -1)
		return true;
	else
		return false;
}
//进栈
bool Push(SqStack& S, int x)
{
	if (S.top == MaxSize - 1)
		return false;		//栈已满,报错
	S.data[++S.top] = x;	//此代码等同于下文两行代码
	//S.top = S.top + 1;
	//S.data[S.top] = x;
	return true;
}
//出栈
bool Pop(SqStack& S, int& x)
{
	if (S.top == -1)
		return false;	//栈为空,报错
	x = S.data[S.top--];//与下文两行代码相同
	//x = S.data[S.top];	
	//S.top--;			//将栈顶减一,即为删除了
	return true;
}
//读取(几乎与出栈相同)
bool GetTop(SqStack& S, int& x)
{
	if (S.top == -1)
		return false;	//栈为空,报错
	x = S.data[S.top];
	return true;
}

         对于top 指针,它还可以指向储存数据的下一位,此时,判断的依据就是 top == 0,进出栈时++、--的顺序也要发生改变,栈满条件:top == MaxSize

        ii.共享栈

        两个栈共享同一片内存(也是顺序储存方式),用于节省内存,一般两个栈分别起始于这片内存的两端,因此,栈满条件就变成了top_0 + 1 == top_1

#define MaxSize 10
//共享栈
class ShStack
{
public:
	int data[MaxSize];
	int top_0;			//0号栈顶指针
	int top_1;			//1号
};
//初始化
void InitStack(ShStack& S)
{
	S.top_0 = -1;
	S.top_1 = MaxSize;
}
//其他操作

        iii.关于销毁

        销毁主要分为两步:

        · 逻辑上的清空

        · 内存的回收

        第一步,就是对 top 的处理;第二步,因为储存用的是数组,数组在运行结束之后会由系统自动回收,所以第二步并没有具体的步骤。

(2).链栈

        用链式储存结构进行储存。

        在上一节中(数据结构(其二)--线性表(其一))单链表的建立,其中的头插法就是一种对链栈的处理。

        主要函数的代码(可运行)

#include<iostream>
using namespace std;

#define MaxSize 10
//链栈
class LinkNode
{
public:
	int data;
	LinkNode* next;
};
using LiStack = LinkNode*;

//初始化(带头结点)
void InitLink(LiStack& S)
{
	S = new LinkNode();
	if (S == nullptr)
		cout << "内存分配失败" << endl;
	S->data = 0;
	S->next = nullptr;
	cout << "初始化成功" << endl;		//检验代码是否可行
}
//初始化(不带头结点)
void InitLink1(LiStack& S)
{
	S = nullptr;
}
//判断空栈(带头结点)
bool Empty(LiStack S)
{
	if (S->next == nullptr)
		return true;
	return false;
}
//判断空栈(不带头结点)
bool Empty1(LiStack S)
{
	if (S == nullptr)
		return true;
	return false;
}
//判断栈满
bool Full(LiStack S)
{
	cout << "满不了一点" << endl;
	return true;
}

//进栈(带头结点)
bool PushLink(LiStack& S, int x)
{
	LinkNode* p = new LinkNode();
	if (p == nullptr)
		return false;
	p->data = x;
	p->next = S->next;
	S->next = p;
	return true;
}
//进栈(不带头结点)
bool PushLink1(LiStack& S, int x)
{
	LinkNode* p = new LinkNode();
	if (p == nullptr)
		return false;
	p->data = x;
	p->next = S;
	S = p;
	return true;
}

//出栈(带头结点)
bool PopLink(LiStack& S, int& x)
{
	if (S->next == nullptr)
		return false;			//栈为空
	LinkNode* p = S->next;
	x = p->data;
	S->next = p->next;
	delete p;
	return true;
}
//出栈(不带头结点)
bool PopLink1(LiStack& S, int& x)
{
	if (S->next == nullptr)
		return false;			//栈为空
	LinkNode* p = S;
	x = p->data;
	S = p->next;
	delete p;
	return true;
}
//打印(带头结点)
void PrintLNode(LiStack S)
{
	LinkNode* p = S->next;
	int i = 1;
	while (p != nullptr)
	{
		
		cout << "第" << i << "个元素:" << p->data << endl;
		i++;
		p = p->next;
	}
	cout << "___________________________" << endl;
}
//打印(不带头结点)
void PrintLNode1(LiStack S)
{
	LinkNode* p = S;
	int i = 1;
	while (p != nullptr)
	{

		cout << "第" << i << "个元素:" << p->data << endl;
		i++;
		p = p->next;
	}
	cout << "___________________________" << endl;
}
//获取栈顶元素(带头结点)
int GetTop(LiStack S)
{
	int a = -1;
	if (S->next == nullptr)
		return -999;			//指示空栈
	a = S->next->data;
	return a;
}
//获取栈顶元素(不带头结点)
int GetTop1(LiStack S)
{
	int a = -1;
	if (S == nullptr)
		return -999;			//指示空栈
	a = S->data;
	return a;
}
//测验
void test01()
{
	LiStack S;
	InitLink(S);
	int a;				//接收出栈元素

	//进栈
	PushLink(S, 1);
	PushLink(S, 2);
	PushLink(S, 3);		//逻辑上,这个是栈顶元素
	PrintLNode(S);
	//出栈
	PopLink(S, a);
	cout << "出栈元素a:" << a << endl;
	PrintLNode(S);
	//获取
	cout << "获取栈顶:" << GetTop(S) << endl;
}

int main()
{
	test01();

	system("pause");
	return 0;
}

6.队列

        队列(Queue)是一种只允许在一端插入、在另一端删除的线性表

        特点:先入队的元素,也会先出队列。(FIFO)

        队头:允许进行删除的一端,称为队头。

        队尾:允许进行插入的一端,称为队尾。

6.1 队列的基本操作

*

InitQueue(&Q):初始化

DestroyQueue(&Q):销毁队列,释放内存。

*

EnQueue(&Q, x):入队,若队列未满,则加入x,成为新的队尾。

DeQueue(&Q, &x):出队,若队列非空,则删除队头,并用x返回。

*

GetHead(Q, &x):读取队头元素,将队头元素用x 传递出来。

*

QueueEmpty(Q):判断队列是否为

6.2 各种队列

(1).循环队列

        数组实现。

        队指针指向 data[0];

        队指针指向存有数据的下一位,队尾指向的永远是的。(借此,进行队列是否已满的检测)

        之所以,称为循环,是因为在入队操作的逻辑中,使用了取余的思想(将无限的数据域控制在有限的范围中)。

        i.代码

#include<iostream>
using namespace std;

#define MaxSize 10
//队列——顺序
class SqQueue
{
public:
	int data[MaxSize];
	int front, rear;	//队头(front)与队尾指针,储存对应下标
	//int size;			//指示长度,此变量依据实际情况添加,有此变量,则可以充分利用内存,无需再牺牲一个单元内存来指示是否已满
	//int tag;			//指示最近一次的操作是删除(0)还是插入(1),也是可以充分利用内存,只有删除(tag==0)时,会使队列为空,只有插入(tag==1)时,会使队列已满,借此再根据两个指针的位置关系判别
};
//初始化
void InitQueue(SqQueue& Q)
{
	Q.front = Q.rear = 0;
	//Q.size = 0;		//若添加了size,之后的函数都要发生一定的变化,不过,本身的逻辑并不会发生多大的变化
	//Q.tag = 0;		//无需与size同时存在
}
//判断空
bool QueueEmpty(SqQueue Q)
{
	if (Q.front == Q.rear)
		return true;
	return false;
}
//判断满
bool QueueFull(SqQueue Q)
{
	if ((Q.rear + 1) % MaxSize == Q.front)	//由此,会牺牲一个单元内存,该内存中不会存储数据
		return true;
	return false;
}

//入队
bool EnQueue(SqQueue& Q, int x)
{
	if (QueueFull(Q))
		return false;
	Q.data[Q.rear] = x;
	Q.rear = (Q.rear + 1) % MaxSize;		//队列指针后移的独特运算方法,太妙了,因为有了模运算,所以其后移也可以做到循环
	return true;

}
//出队
bool DeQueue(SqQueue& Q, int& x)
{
	if (QueueEmpty(Q))
		return false;
	x = Q.data[Q.front];
	Q.front = (Q.front + 1) % MaxSize;		//因为是数组存储,所以不需要额外的释放操作
	return true;
}
//获取元素
bool GetHead(SqQueue Q, int& x)
{
	if (QueueEmpty(Q))
		return false;
	x = Q.data[Q.front];
	return true;
}
//获取元素个数
int GetLength(SqQueue Q)
{
	return((Q.rear + MaxSize - Q.front) % MaxSize);	//队列的长度计算公式
}
//打印全队列
bool PrintQueue(SqQueue Q)
{
	if (QueueEmpty(Q))
		return false;
	int i = Q.front;
	int cont = 1;
	while (i != Q.rear)
	{
		cout << "第" << cont << "个数是:" << Q.data[i] << endl;
		i++;
		cont++;
	}
	cout << "当前元素个数:" << GetLength(Q) << endl;
	cout << "-------------------" << endl;
	return true;
}
//测验
void test01()
{
	SqQueue q;
	InitQueue(q);

	cout << "当前元素个数:" << GetLength(q) << endl;
	//入队
	EnQueue(q, 1);
	EnQueue(q, 2);
	EnQueue(q, 3);
	PrintQueue(q);
	//出队
	int a;
	DeQueue(q, a);
	cout << "出队元素:" << a << endl;
	PrintQueue(q);
}
int main()
{
	test01();

	system("pause");
	return 0;
}

        ii.另外一种写法

        rear 指向data 的最后一位元素,而非其下一位了。

        那么,其队列的各个函数就要发生一些变化。        

        的判断标准:(Q.rear + 1) % MaxSize == Q.front。

        初始化:rear = MaxSize - 1;即零的前一位,如此方便插入。

        插入rear 指针,进行数据的赋值

        删除:也是类似。

Q.rear = (Q.rear + 1) % MaxSize;

Q.data[Q.rear] = x;

        的判断方法:

        方法一牺牲一个存储单元,使得front的前一个位置不能存放数据,则当(Q.rear + 2) % MaxSize == Q.front;时,即为满。

        方法二引入一个记录的变量,如size,tag等。

(2).链式队列

        i.代码

        值得注意:

        · 链式队列的类的定义,有两个

#include<iostream>
using namespace std;

class LinkNode
{
public:
	int data;
	LinkNode* next;
};
//链式队列——记录一个链表只需要保存他的头指针即可
class LinkQueue
{
public:
	LinkNode* front, * rear;
};

//初始化(带头结点)
void InitQueue(LinkQueue& Q)
{
	Q.front = Q.rear = new LinkNode();
	Q.front->next = nullptr;
}
//初始化(不带头结点)
void InitQueue1(LinkQueue& Q)
{
	Q.front = nullptr;
	Q.rear = nullptr;
}

//判空(带头结点)
bool QueueEmpty(LinkQueue& Q)
{
	if (Q.front == Q.rear)
		return true;
	return false;
}
//判空(不带头结点)
bool QueueEmpty1(LinkQueue& Q)
{
	if (Q.front == Q.rear && Q.front == nullptr)
		return true;
	return false;
}


//入队(带头结点)(只能尾插)
bool EnQueue(LinkQueue& Q, int x)
{
	LinkNode* p = new LinkNode();
	p->data = x;
	p->next = nullptr;
	Q.rear->next = p;
	Q.rear = p;
	return true;
}
//入队(不带头结点)(只能尾插)
bool EnQueue1(LinkQueue& Q, int x)
{
	LinkNode* p = new LinkNode();
	p->data = x;
	p->next = nullptr;
	if (Q.front == nullptr)		//空队列时,无头结点,直接称为第一个结点
	{
		Q.front = p;
		Q.rear = p;
	}
	else
	{
		Q.rear->next = p;
		Q.rear = p;
	}
	return true;
}
//出队(带头结点)
bool DeQueue(LinkQueue& Q, int& x)
{
	if (Q.front == Q.rear)
		return false;
	LinkNode* p = Q.front->next;		//设置一个临时结点,指向队头
	x = p->data;
	Q.front->next = p->next;			//绕开队头结点
	if (Q.rear == p)					//如果队头结点就是队尾结点,那么还需要更新rear 指针
		Q.rear = Q.front;
	free(p);
	return true;
}
//出队(不带头结点)
bool DeQueue1(LinkQueue& Q, int& x)
{
	if (Q.front == Q.rear)
		return false;
	LinkNode* p = Q.front;
	x = p->data;
	Q.front = p->next;			
	if (Q.rear == p)
	{
		Q.front = nullptr;
		Q.rear = nullptr;
	}
	free(p);
	return true;
}
//链式队列不会有队满情况
//打印全队(带头结点)
bool PrintLQueue(LinkQueue Q)
{
	if (QueueEmpty(Q))
		return false;
	LinkNode* p = Q.front->next;
	int i = 1;
	while (1)
	{
		cout << "第" << i << "个元素:" << p->data << endl;
		if (p == Q.rear)
			break;
		p = p->next;
		i++;
	}
}
//打印全队(不带头结点)
bool PrintLQueue1(LinkQueue Q)
{
	if (QueueEmpty1(Q))
		return false;
	LinkNode* p = Q.front;
	int i = 1;
	while (1)
	{
		cout << "第" << i << "个元素:" << p->data << endl;
		if (p == Q.rear)
			break;
		p = p->next;
		i++;
	}
}

void test04()
{
	LinkQueue Q;
	InitQueue1(Q);

	//入队
	EnQueue1(Q, 1);
	EnQueue1(Q, 22);
	EnQueue1(Q, 333);
	PrintLQueue1(Q);
	//出队
	int a = 0;
	DeQueue1(Q, a);
	cout << "出队元素:" << a << endl;
	PrintLQueue1(Q);
}
int main()
{
	test04();

	system("pause");
	return 0;
}

(3).双端队列

        允许在从线性表的两端进行插入删除。 

        双端队列也会由此衍生一些变种,如下

        以上类型队列,在考研中,常考,给定输入的元素顺序,求合法的出队序列

        一般,首先,有出队的第一个元素判断队列中已有的元素,根据具体队列的插入删除性质来判断是否合法。 

7.栈在括号匹配中的应用

        用以处理复杂式子中的各种括号的配对{ [ ( ) ] }

       i.主要思路

        遇到括号就入栈,遇到括号就弹出栈顶,并与之进行匹配,成功则继续,失败则直接结束。

       ii.代码

#include<iostream>
using namespace std;

#define MaxSize 10	//
//顺序栈
class SqStack           //sequence stack
{
public:
	char data[MaxSize];	//静态数组存放栈元素
	int top;			//栈顶指针,储存栈顶的数组下标
};

//初始化
void InitStack(SqStack& S)
{
	S.top = -1;			//初始化栈顶指针
}
//判断栈是否为空
bool StackEmpty(SqStack S)
{
	if (S.top == -1)
		return true;
	else
		return false;
}
//进栈
bool Push(SqStack& S, char x)
{
	if (S.top == MaxSize - 1)
		return false;		//栈已满,报错
	S.data[++S.top] = x;	//此代码等同于下文两行代码
	//S.top = S.top + 1;
	//S.data[S.top] = x;
	return true;
}
//出栈
bool Pop(SqStack& S, char& x)
{
	if (S.top == -1)
		return false;	//栈为空,报错
	x = S.data[S.top--];//与下文两行代码相同
	//x = S.data[S.top];	
	//S.top--;			//将栈顶减一,即为删除了
	return true;
}


//括号匹配
bool bracketCheck(char str[], int length)	//length是传入数组的长度
{
	SqStack S;
	InitStack(S);
	for (int i = 0; i < length; i++)
	{
		if (str[i] == '(' || str[i] == '[' || str[i] == '{')
		{
			Push(S, str[i]);	//将扫描的左半边括号存入栈中
		}
		else
		{
			if (StackEmpty(S))	//如果是空栈,则匹配失败
				return false;
			char topElem;		//接收栈顶元素
			Pop(S, topElem);
			if (str[i] == ')' && topElem != '(')
				return false;
			if (str[i] == '[' && topElem != ']')
				return false;
			if (str[i] == '{' && topElem != '}')
				return false;
		}
	}
	return StackEmpty(S);		//最终,栈为空则说明匹配成功

8.栈在表达式求值中的应用

       (1).中缀表达式

        日常最常见的(最习惯的)就是中缀表达式,如下

(1+(3+4)*8)-1

        意为,加减乘除在式子之中。

        (2).前缀表达式

        前缀表达式,就是加减乘除排列在前面,如

+ a b

        (3).后缀表达式

        后缀表达式(逆波兰表达式)(此表达式应用更加广泛),即加减乘除在数字之后排列,如

a b + 就是 a+b,a b的配列顺序不可发生改变

        i.中缀转后缀

a + b - c => a b + c -

每一个子式,包括两个数一个运算符,子式还可以与其他数字、运算符组合构成新的子式,

其中a b +,就可以看作一个子式,其与c -构成了又一个式子

*

对于复杂的式子,如A + B - ( C * D + E) + F

遵循优先原则,先转换A + B,再向右依次转换,得到A B + C D * E + - F +

        ii.后缀的运算(手算)

        如上文中的A B + C D * E + - F +,从左往右找,到第一个运算符,则弹出此处之前的两个数(A B),进行对应的运算,再将所得的数存入其中,继续从左往右遍历,以此类推,得出最终结果。

        iii.中缀转前缀

        遵循优先原则,如

A + B * (C - D) - E / F

按照原则,可转换为

+ A - * B - C D / E F

        实际的转换结果可有很多形式,这些转换的原则,只是为了统一格式

        iiii.前缀的运算(手算)

        与后缀类似,只要从右往左遍历,其他雷同。(注意加减乘除的操作数顺序)

        iiiii.中缀转后缀(机算)

        机算的基本原则(有运算符、界限符会入栈、出栈,操作数会直接加入后缀表达式):


        · 遇到操作数,直接加入后缀表达式

        · 遇到界限符,遇到“(” 入栈,遇到 “)”则依次弹出栈内运算符,并加入后缀表达式,直到弹出“)”为止,在没遇到“)”之前,按正常的逻辑来,该弹的弹,该入的入,但是,所谓的逻辑是在括号的,也就是说,在“(”之前入栈的不遵循括号内的逻辑,如,括号外有个*,括号内遇到了-,此时并不会把括号外的那个* 弹出。

        · 遇到运算符,依次弹出栈中优先级高于或等于当前运算符的所有运算符,并加入后缀表达式,

        · 处理完所有字符之后,将栈中剩余的运算符依次弹出,若栈空则无需此操作

9.栈在递归中的应用

        在递归函数的调用中,其底层逻辑就是栈。

10.队列的应用(以后会学到)

        · 树的层次遍历

        · 图的广度优先遍历

        · 在操作系统的应用——多进程调用系统资源时,系统对这些进程的处理原则就是队列的思想,先来先服务(FCFS)

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

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

相关文章

[Latex美化]-表格加底色,添加灰色美化表格,便于阅读

1 导入库 \usepackage{xcolor} \usepackage{colortbl, booktabs} 2 插入指令&#xff08;指定行前&#xff09; \rowcolor{gray!30} 具体代码如下 效果如下

循环神经网络RNN介绍

文章目录 1、学习介绍2、RNN的基本结构2.1、图例2.2、公式2.3、公式计算示例2.3.1、给定参数2.3.2、时间步计算 3、序列依赖与梯度消失/爆炸3.1、序列依赖3.2、梯度消失与爆炸3.3、总结 4、传统的前馈神经网络4.1、结构4.2、工作原理4.3、特点4.4、局限性 5、CNN与RNN的关系5.1…

【建造者模式】全面解析与最佳实践:打造复杂对象的蓝图(构建复杂对象的艺术)

文章目录 Java中的建造者模式&#xff1a;全面解析与最佳实践1. 引言2. 建造者模式概念定义与用途适用场景解决的问题 3. 建造者模式原理主要角色解释工作流程UML图和时序图 4. 建造者模式在Java中的实现逐步构建示例程序1. 创建抽象建造者类2. 实现具体建造者类3. 设计产品类4…

如何在厂商软件不提供二次开发资源的情况下实现LabVIEW开发

在遇到厂商提供的软件不支持二次开发资源时&#xff0c;如果需要使用LabVIEW进行开发&#xff0c;通常面临以下几个挑战&#xff1a;设备通讯接口封闭、协议不公开、厂商技术支持有限等。这些问题需要综合考虑并制定解决方案&#xff0c;以下是详细的分析&#xff1a; 1. 了解原…

权限模块开发+权限与角色关联(完整CRUD)

文章目录 &#x1f31e; Sun Frame&#xff1a;SpringBoot 的轻量级开发框架&#xff08;个人开源项目推荐&#xff09;&#x1f31f; 亮点功能&#x1f4e6; spring cloud模块概览常用工具 &#x1f517; 更多信息1.easycode生成代码1.配置2.AuthPermissionDao.java剪切到mapp…

SharpLab:.Net反编译工具,方便实时查看反编译后的代码!

C#提供了很多高级语法&#xff0c;很多都是语法糖。这些语法糖对于初学者来说&#xff0c;很多无法理解。 下面推荐一个开源项目&#xff0c;它能够让我们&#xff0c;实时查看编译过程、生成的中间语言&#xff08;IL&#xff09;以及反编译后的代码。 01 项目简介 SharpLa…

C语言 ——深入理解指针(2)

目录 1. 数组名的理解2. 二级指针3. 指针数组4. 字符指针变量5. 数组指针变量6. 函数指针变量7. 函数指针数组 1. 数组名的理解 这里我们使用 &arr[0] 的方式拿到了数组第一个元素的地址&#xff0c;但是其实数组名本来就是地址&#xff0c;而且是数组首元素的地址&#x…

TabLayout使用以及自定义tab标签

<?xml version"1.0" encoding"utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.android.com/apk/res-auto"xmlns:tool…

YoloV10 论文翻译(Real-Time End-to-End Object Detection)

​摘要 近年来&#xff0c;YOLO因其在计算成本与检测性能之间实现了有效平衡&#xff0c;已成为实时目标检测领域的主流范式。研究人员对YOLO的架构设计、优化目标、数据增强策略等方面进行了探索&#xff0c;并取得了显著进展。然而&#xff0c;YOLO对非极大值抑制&#xff0…

01【功能项目】之【主角射线点击导航】

首先创建一个Unity3D的项目 打开资源商店添加一个人物模型 选择一个免费资源主角添加至项目中 在unity中打开后点击下载包 点击导入包 导入成功后会出现在资源包Assets下 右键创建地面 设置地面尺寸 创建一个材料方便给地面调配颜色 选择材料的颜色 将材质拖拽给地面组为组件 将…

double类型 精度丢失的问题

前言 精度丢失的问题是在其他计算机语言中也都会出现&#xff0c;float和double类型的数据在执行二进制浮点运算的时候&#xff0c;并没有提供完全精确的结果。产生误差不在于数的大小&#xff0c;而是因为数的精度。 一、double进行运算时,经常出现精度丢失 0.10.2使用计算…

QTableView使用示例-Qt模型视图代理(Model-View-Delegate)使用示例

模型视图委托&#xff08;MVD&#xff09;是Qt中特有的设计模式&#xff0c;类似MVC设计模式&#xff0c;将MVC设计模式中的Controller当做MVD中的Delegate&#xff0c;两者的概念基本相同。不同的是委托不是独立存在&#xff0c;而是包含在视图里面。 模型视图委托设计模式中&…

#71结构体案例2(三国游戏,冒泡排序)

效果&#xff1a; 代码&#xff1a; #include <iostream> #include <string> using namespace std;//英雄结构体 struct Hero {string name;int age;string gender; };//冒泡排序 void bubbleSort(struct Hero hArray[],int len) {for(int i0;i<len-1;i){for(i…

CentOS 8 本地创建yum源

1.获取iso (有iso就可以建立本地repo) 如CentOS-8.5.2111-aarch64-dvd1.iso 2.解压iso&#xff08;mount挂载就可以吧iso解压到linux某一目录中&#xff09; mkdir /mnt/cdrom mount -o loop ./CentOS-Stream-8-aarch64-20220913-dvd1.iso /mnt/cdrom ls /mnt/cdrom 3.编…

奇偶函数的性质及运算

目录 定义 注意 特征 运算 拓展 定义 设函数f(x)的定义域D&#xff1b; 如果对于函数定义域D内的任意一个x&#xff0c;都有f(-x)&#xff0d;f&#xff08;x&#xff09;&#xff0c;那么函数f&#xff08;x&#xff09;就叫做奇函数。如果对于函数定义域D内的任意一个x…

【前端】 如何在 Vue.js 中使用 Mock 数据:教程与技巧

如何在 Vue.js 中使用 Mock 数据&#xff1a;教程与技巧 在开发过程中&#xff0c;为了测试和开发前端功能&#xff0c;你常常需要用到模拟&#xff08;mock&#xff09;数据。Vue.js 提供了灵活的方式来处理数据请求和更新&#xff0c;但在没有真实后端的情况下&#xff0c;我…

在 VueJS 中使用事件委托处理点击事件(事件委托,vue事件委托,什么是事件委托,什么是vue的事件委托)

前言 在开发 Vue 项目时&#xff0c;我们经常需要处理大量的点击事件。为每个可点击的元素单独添加事件监听器不仅会增加代码的复杂度&#xff0c;还会降低性能。事件委托是一种有效的优化方式&#xff0c;它可以显著减少事件监听器的数量&#xff0c;提高代码的可维护性和执行…

SSM禾泽校园学生商品交易平台-计算机毕设定制-附项目源码(可白嫖)50284

摘 要 信息化社会内需要与之针对性的信息获取途径&#xff0c;但是途径的扩展基本上为人们所努力的方向&#xff0c;由于站在的角度存在偏差&#xff0c;人们经常能够获得不同类型信息&#xff0c;这也是技术最为难以攻克的课题。针对禾泽校园学生商品交易平台等问题&#xff0…

部署PXE

一 准备工作 1.rhel7主机 2.开启主机图形init 5 开图形 3.配置网络可用 4.关闭vmware dhcp功能 将VMnet8本地DHCP服务关闭 二 部署kickstart 1.安装kichstart并开启 2.安装httpd并启动 3.测试 4.配置kickstart 左上角文件保存 在vim ks.cfg中配置软件 共享 测试 四 DHCP 1.…

mysql操作(进阶)

1.数据库约束 数据库自动对数据的合法性进行校验检查的一系列机制&#xff0c;目的是为了保证数据库中能够避免被插入或者修改一些非法数据。 &#xff08;1&#xff09;mysql中提供了以下的约束&#xff1a; a.NOT NULL&#xff1a;指定某列不能为null b.UNIQUE&#xff1…