首页 > 其他分享 >数据结构——队列

数据结构——队列

时间:2024-09-12 21:52:06浏览次数:13  
标签:结点 队列 Elemtype MaxSize front 数据结构 data rear

1、定义

从栈的学习我们知道栈是只允许在一端进行插入或删除操作的线性表。

而队列:是只允许在一端进行插入另一端删除的线性表。在生活中比如说到饭堂排队打饭,一端进一端出,这就是队列。

2、队列顺序实现

2.1、队列的基本形式

typedef int Elemtype;//需要时可以改为自己需要的元素类型
#define MaxSize 10  //定义队列中元素的最大值
typedef struct {
	Elemtype data[MaxSize];//用静态数组存放列表元素
	int front, rear;//队头指针和队尾指针
}SqQueue;

void textQueue()
{
	SqQueue Q;
}

2.2、入队操作

typedef struct {
	Elemtype data[MaxSize];//用静态数组存放列表元素
	int front, rear;//队头指针和队尾指针
}SqQueue;


bool QueueEmpty(SqQueue &Q)
{
	if (Q.front == Q.rear)//队空条件
		return false;
	else 
		return true;
}
//入队
bool EnterQueue(SqQueue& Q, Elemtype x)
{
	if ((Q.rear+1)%	MaxSize==Q.front)
		return false;//队满则报错
	Q.data[Q.rear] = x;//新元素加入队尾
	Q.rear = (Q.rear + 1) % MaxSize;//队尾指针加一取模
	return true;
}
Q.rear = (Q.rear + 1) % MaxSize;

许多人看到这一条就会疑惑,为什么要加一取模?

队列并没有所规定的头或尾,如果加到data[MaxSize],而data[0]没有元素,便能将元素加到data[0],而不用浪费空间。这样操作便能将队列在存储空间在逻辑上变成了“环状”。

用模运算便能从最大值变为最小值:例如你现在元素存储到data[9],(9+1)%10=0,你的下一个元素便能存储到data[0]。

2.3、出队操作

进行出队操作时要记住一件事:只能让对头元素出队!

typedef int Elemtype;//需要时可以改为自己需要的元素类型
#define MaxSize 10  //定义队列中元素的最大值
typedef struct {
	Elemtype data[MaxSize];//用静态数组存放列表元素
	int front, rear;//队头指针和队尾指针
}SqQueue;

//出队(删除一个队头元素,并用x返回)
bool DeleteQueue(SqQueue &Q,Elemtype x)
{
	if (Q.rear == Q.front)//判断队空
		return false;//队空则判错
	x = Q.data[Q.front];
	Q.front = (Q.front + 1) % MaxSize;//队头指针后移
	return true;
}

注:入队还是出队都是让指针后移一位

2.4、获得队头元素

获得队头元素这个操作与出队相似,不过获得队头元素只是将队头元素通过x返回,并不改变队列里的数据。

bool GetHead(SqQueue& Q, Elemtype &x)
{
	if (Q.rear == Q.front)//判断队空
		return false;//空则判错
	x = Q.data[Q.front];
	return true;
}

2.5、判断队空/队满

一般来说队空/队满很容易判断,这里给出两个方法:

(1)计算出队列中的元素个数:(rear+MaxSize-front)%MaxSize

队满条件是(Q.rear + 1) % MaxSize ==Q.front,队空条件是rear=front。   

(2)设置一个长度,在入队或出队过程中进行计算:

typedef int Elemtype;//需要时可以改为自己需要的元素类型
#define MaxSize 10  //定义队列中元素的最大值
typedef struct {
	Elemtype data[MaxSize];//用静态数组存放列表元素
	int front, rear;//队头指针和队尾指针
	int size;
}SqQueue;

 初始化为rear=front=0,size=0

队满条件是size==MaxSize,队空条件是size==0。

3、队列的链式实现

3.1、链式队列的一个结点

typedef int Elemtype;
typedef struct LinkNode {//链式队列结点
	Elemtype data;
	struct LinkNode* next;
}LinkNode;

typedef struct {//链式队列
	LinkNode* front, *rear;//队列的队头和队尾指针
}LinkQueue;

3.2、初始化(带头结点)

//初始化队列(带头结点)
void InitQueue(LinkQueue& Q)
{
	Q.front = Q.rear=(LinkNode*)malloc(sizeof(LinkNode));
	Q.front->next = NULL;
}
//判断队列是否为空
bool IsEmpty(LinkQueue& Q)
{
	if (Q.front == Q.rear)
		return true;
	else
		return false;
}

3.3、入队(带头结点)

//新元素入队(带头结点)
void EnQueue(LinkQueue &Q,Elemtype x)
{
	LinkNode* s = (LinkNode*)malloc(sizeof(LinkNode));
	s->data = x;
	s->next = NULL;
	Q.rear ->next= s;//新结点插入到rear后面
	Q.rear = s;//修改表尾指针
}

3.4、入队(不带头结点)

//新元素入队(不带头结点)
void EnQueue(LinkQueue& Q, Elemtype x)
{
	LinkNode* s = (LinkNode*)malloc(sizeof(LinkNode));
	s->data = x;
	s->next = NULL;
	if (Q.front = NULL)//在空列中插入第一个元素
	{
		Q.front = s;//修改队头队尾指针
		Q.rear = s;
	}
	else {
		Q.rear->next = s;//新结点插入到rear后面
		Q.rear = s;//修改表尾指针
	}
}

3.5、出队(带头结点)

//出队(带头结点)
bool DeQueue(LinkQueue& Q, Elemtype& x)
{
	if (Q.front == Q.rear)//空队返回
		return false;
	LinkNode* p = Q.front->next;//
	x = p->data;//用变量x返回队头指针
	Q.front->next = p->next;//修改头结点的next指针
	if (Q.rear = p)//此次是最后一个结点出队
		Q.rear = Q.front;//修改rear指针
	free(p);//释放结点空间
	return true;
}

3.6、出队(不带头结点)

//出队(不带头结点)
bool DeQueue(LinkQueue& Q, Elemtype& x)
{
	if (Q.front == NULL)
		return false;//空队
	LinkNode* p = Q.front;//p指向出队的头结点
	x = p->data;//用x返回队头元素
	Q.front = p->next;//修改front指针
	if (Q.rear == p)//此次是最后一个结点出队
	{
		Q.front = NULL;//front指向NULL
		Q.rear = NULL;//rear指向NULL
	}
	free(p);
	return true;
}

标签:结点,队列,Elemtype,MaxSize,front,数据结构,data,rear
From: https://blog.csdn.net/2301_79654372/article/details/140589642

相关文章

  • 数据结构与算法chapter-0
    /**Aninterfaceformethodsthatreturntheperimeterandareaofanobject.@[email protected]*/publicinterfaceMeasurable{/**Getstheperimeter.@returnTheperimeter.*/publicdoublegetPerimeter()......
  • 等待唤醒机制和阻塞队列
     1.等待唤醒机制由于线程的随机调度,可能会出现“线程饿死”的问题:也就是一个线程加锁执行,然后解锁,其他线程抢不到,一直是这个线程在重复操作voidwait()当前线程等待,直到被其他线程唤醒voidnotify()随机唤醒单个线程voidnotifyAll()唤醒所有线程等待(wa......
  • 算法与数据结构——二分查找插入点
    二分查找插入点二分查找不仅可用于搜索目标元素,还可以解决许多变种问题,比如搜索目标元素的插入位置。无重复元素情况Question给定一个长度为n的有序数组nums和一个元素target,数组不存在重复元素。现将target插入数组nums中,并保持其有序性。若数组中已存在元素target,则插入到......
  • Java-数据结构-二叉树-基础 (o゚▽゚)o
    文本目录:❄️一、树形结构:  ▶ 1、概念:▶ 2、特殊的概念: ▶ 3、树的表示形式:❄️二、二叉树:  ▶ 1、概念:   ▶2、两种特殊的二叉树:     ➷1)、满二叉树:      ➷ 2)、完全二叉树:  ▶3、二叉树的性质:    ➷ 1)性质一:  ......
  • 【项目实战】Redis使用场景之基于Redis实现分布式队列
    一、什么是分布式队列分布式队列,指在分布式系统中用于协调不同服务或组件之间的消息传递和任务调度的队列。分布式队列,允许多个生产者将任务放入队列,而多个消费者可以从队列中取出任务进行处理。分布式队列,在微服务架构、任务调度、消息传递等场景中非常有用。二、为什......
  • 消息队列架构解析:从设计到实现的全面解析
    消息队列是现代分布式系统中常见的核心组件之一,广泛用于解耦系统、提升系统性能、实现异步通信和处理高并发。通过消息队列,应用程序可以在不同服务之间高效地传递数据或命令,避免同步操作中的阻塞问题。本文将通过详细的架构图及深入的分析,全面解析消息队列的工作机制、常见的消息队......
  • 算法与数据结构——二分查找
    二分查找二分查找(binarysearch)是一种基于分治策略的高效搜索算法。它利用数据的有序性,每轮缩小一半搜索范围,直至找到目标元素或搜索区间为空为止。Qustion:给定一个长度为n的数组nums,元素按从小到大的顺序排列且不重复。请查找并返回元素target在该数组中的索引。若数组不包含......
  • RabbitMQ的队列模式你真的懂吗
    0前言官网描述六类工作队列模式:简单队列模式:最简单的工作队列,一个消息生产者,一个消息消费者,一个队列。另称点对点模式工作模式:一个消息生产者,一个交换器,一个消息队列,多个消费者。也称点对点模式发布/订阅模式:无选择接收消息,一个消息生产者,一个交换器,多个消息队列,多个消费者......
  • 单调队列优化 DP
    单调队列优化DP回忆单调队列的作用,\(O(n)\)求出每一个大小为\(K\)的窗口中的最大、最小值。以最大值为例,我们可以得到如下DP转移方程:\[dp[i]=\max(val[j])+base[i],i-j\leqK\]其中\(base[i]\)是一个仅与\(i\)有关的式子,不受\(j\)影响,且可以预处理得到;而\(val[j]......
  • 56.《数据结构-线性表白话看》
    知识参考王道考研硬看知识和视频一直瞌睡无聊破了两天题才寻得规律故在此记录分为顺序存储和链式存储线性表的定义:具有相同数据类型的n个数据元素的有限序列注意相同数据类型有限序列还有就是线性表是一种逻辑结构顺序表和链表是存储(物理)结构1.顺序存储即顺序表......