首页 > 其他分享 >数据结构复习笔记4:队列,双端队列,循环队列

数据结构复习笔记4:队列,双端队列,循环队列

时间:2024-06-01 14:33:26浏览次数:23  
标签:maxx 队列 双端 next int front 数据结构 data

1.队列概念和特点

        队列是⼀种特殊的线性表,特殊之处就在于它只允许在表的前端进⾏删除操作,在表的后端进⾏ 插⼊操作。和栈⼀样,队列也是⼀种操作受到限制的线性表。进⾏插⼊操作的端称之为队尾,进⾏删除 操作的端称之为队头。队列中没有队列的时候,称之为空队列。队列的数据元素,⼜叫做队列元素。在 队列中插⼊⼀个队列元素称之为⼊队,在队列中删除⼀个队列元素,称之为出队。因为队列只允许在⼀ 端插⼊,在另⼀端删除,所以只有最早进⼊的队列元素才可以从队列中删除,故队列⼜称为先进先出线性表。

队列的表示和实现(存储结构)

链队列 :采用链式存储结构的队列

顺序队列 :采用顺序存储结构的队列

队列的操作包括初始化、销毁、入队、出队、获取队首元素、获取队尾元素以及检查队列是否为空等。

2.顺序队列

        当我⽤⼀⽚连续的存储空间来存储队列中的数据元素的时候,这样的队列就称之为顺序队列。类似于顺序栈。⽤⼀维数组来存放顺序队列中的数据元素。队头设置在最近⼀个离开队列元素所占的位置。队尾设置在最近⼀个进⾏⼊队列的元素位置。那么队头和队尾随着插⼊和删除的变化⽽变化。当队列为空时,front = rear;队列中的元素个数可以由队头 - 队尾求得。

假溢出

        但是,这个时候,会有⼀个问题。当我们的队尾指针指向size - 1 时,代表⻓度已满。但是根据队 列的规则,就实际情况来说,他还有空闲的空间。那么这个时候,我们就将其称之为假溢出。

        为了解决假溢出的问题,就是将我们的顺序队列看成是⾸位相接的循环结构。⾸尾指示器不变, 这种队列就叫做,循环顺序队列。

        也就是说,当我们的队尾元素达到数组的上限时,如果还有数据元素⼊队并且数组的第0个空间是 空闲时,队尾指示器就指向数组的0端,所以。整个队尾指示器+1的操作就可以修改为:rear = (rear + 1)%maxSize;队头指示器同样是如此。当队头的操作达到数组的上限的时候,如果还有数组元素出 队,这个时候,队头指示器就要指向数组的0端。所以,队头指示器+1的操作就是 front = (front + 1)%maxSize。

        这样的话,就⼜有⼀个问题,队满和队空的时候,都有rear = front。为了解决这个问题,⼀般的 ⽅法就是,少使⽤⼀个空间。所以,我们判断队空的条件就变成了 rear = front。判断队满的条件是 (rear + 1)%maxSize = front。与此同时,循环队列中数据元素的个数是(rear - front + maxSize)% maxSize。

所以普通队列的实现我们用链式存储结构。

3.链队列的代码实现

1.结点结构
///链式队列//
typedef struct qnode{//链式队列结点 
	int data;//队列元素
	struct qnode *next;//指向下一个结点的指针 
}qnode,*lqueue; 

typedef struct linkqueue{//链式队列---可选,不写结构体,直接定义对头队尾指针也可 
	lqueue front,rear;//队头队尾指针,队首指针是链表头结点 
}linkqueue;
2.初始化
//初始化
void initqueue(linkqueue *q)
{   
	q->front=q->rear=(lqueue)malloc(sizeof(qnode));
    if(q->front==NULL)
    {
    	printf("分配失败\n");
	}
	else{
		q->front->next=NULL;
	}
 } 
3.入队
//入队 
void enqueue(linkqueue* q,int x)
{
	lqueue s=(lqueue )malloc(sizeof(qnode));
	s->data =x;
	s->next =NULL;//新节点插入到链尾
	q->rear->next=s;
	q->rear =s; 
 } 
4.出队
//出队,队首指针是链表头结点 ,删除的是队首指针的下一个,即front->next 
void dequeue(linkqueue* q) 
{
	int x;//保存出队元素 
	//先判空,不空才能出 
	if(q->front->next==NULL)
	{
		printf("空\n");//队空,报错 
	 } 
	else{
		lqueue p=q->front->next; 
		x=p->data;
		q->front ->next=p->next ;
		printf("%d\n",x);
		//若原队列只有一个结点了,则删除边空,需要处理尾指针 
		if(q->rear==p)
		q->rear =q->front;
		free(p); 
		p=NULL;
	}
}

4.顺序实现循环队列

1.结点结构
//循环队列 
typedef struct
{
	int* data;//指针模拟开数组 
	int f,r;//本质是下标 	
}squeue; 
2.初始化
//初始化
squeue initqueue()
{
	squeue q;
	q.data=(int*)malloc(sizeof(int)*maxx);
	q.f=q.r=0;
	return q;
 } 
3.入队
//入队---->前提先判满 
void enqueue(squeue* q,int k)
{
	//判满
	if(q->f==((q->r+1)%maxx)) 
	{
		printf("队满\n");
		return; 
	}
	q->data[q->r]=k;
	q->r=(q->r+1)%maxx; 
 } 
4.出队
//出队 --->前提 判空 
void dequeue(squeue* q) 
{
	//判空
	if(q->r==q->f)
	{
		printf("队空\n");
		return ; 
	 } 
	 q->f=(q->f+1)%maxx;
}

5.双端队列

1.特点

        对于双端队列来说,就是两端都是结尾的队列。队列的每⼀端都可以插⼊数据项和移除 数据项。相对于普通队列。双端队列的⼊队和出队操作在两端都可以进进⾏。

        这种数据结构的特性,使得他更加的实⽤和⽅便。当你只允许使⽤⼀端出队、⼊队操作的时候, 他等价于⼀个栈。当限制⼀端只能出队,另⼀端只能⼊队,他就等价于⼀个普通队列。

2.双端队列链式存储全操作展示
#define maxx 10
typedef struct Node{
	int data;
	struct Node* pre;
	struct Node* next;
}node; 
//中间节点存储右端第一次插入的数据
node* l;
node* r;
void initqueue()
{
	node* s=(node*)malloc(sizeof(node));
	s->pre=s->next=NULL;
	l=r=s;
}
//左边插入
void left_insert(int k)
{//l 指向真实的左端数据 
	node* s=(node*)malloc(sizeof(node));
	s->data=k;
	s->pre=NULL;
	l->pre=s;
	s->next=l;
	l=s;
} 
//右插入
void right_insert(int k)
{
	//r 指向真实的右端数据的下一个节点 
	node* s=(node*)malloc(sizeof(node));
	r->data=k;
	r->next=s;
	s->next=NULL;
	s->pre=r;
	r=s; 
} 
//左删除 
void left_del()
{
	if(l==r)
	{
		printf("空\n");
		return;
	 } 
	 node* p=l;
	 l=l->next;
	 l->pre=NULL;
	 printf("删除了%d\n",p->data);
	 free(p);
	 p=NULL;
 } 
 //右删除
void right_del()
{
	if(l==r)
	{
		printf("空\n");
		return;
	 } 
	 node* p=r;
	 r=r->pre;
	 r->next=NULL;
	 printf("删除了%d\n",r->data);
	 free(p);
	 p=NULL;
} 
3.双端队列顺序存储全操作展示
#define maxx 10
typedef struct {
	int *data;
	int l,r;
	int sum;//元素个数 
}douqueue; 
douqueue initqueue()
{
	douqueue q;
	q.data=(int *)malloc(sizeof(int)*maxx);
	q.l=q.r=0;
	q.sum=0;
	return q;
}
//左端插入
void left_insert(douqueue *q,int k)
{
	if(q->sum==maxx)
	{
		printf("满\n");
		return;
	 } 
	 q->data[q->l]=k;
	 q->l=(q->l+maxx-1)%maxx;//
	 q->sum++;
}
//左端删除
void left_delet(douqueue *q) 
{
	int x;//保存删除的元素
	if(q->sum==0)
	{
		printf("空\n");
		return;
	 } 
	x=q->data[(q->l+1)%maxx];
	printf("删除了%d\n",x);
	q->l=(q->l+1)%maxx;
	q->sum--;
}
//右端插入
void right_insert(douqueue *q,int k)
{
	if(q->sum==maxx)
	{
		printf("满\n");
		return;
	 } 
	 q->r=(q->r+1)%maxx;
	 q->data[q->r]=k;
	 q->sum++;
}
//右端删除
void right_delet(douqueue *q) 
{
	int x;//保存删除的元素
	if(q->sum==0)
	{
		printf("空\n");
		return;
	 } 
	x=q->data[q->r];
	printf("删除了%d\n",x);
	q->r=(q->r-1+maxx)%maxx;//
	q->sum--;
} 

标签:maxx,队列,双端,next,int,front,数据结构,data
From: https://blog.csdn.net/2301_81070376/article/details/139371938

相关文章

  • 【数据结构】二叉树-堆(下)-链式二叉树
    个人主页~二叉树-堆(上)栈和队列二叉树四、堆的代码实现Heap.hHeap.ctest.c五、堆的应用堆排序思想进行排序六、二叉树链式结构的实现BTree.hBTree.ctest.c四、堆的代码实现Heap.h#pragmaonce#include<stdio.h>#include<stdlib.h>#include<assert.h>......
  • 【数据结构】二叉树
    【数据结构】二叉树树树的概念树的相关概念树的注意事项左孩子右兄弟表示法树实际中的应用二叉树二叉树的概念二叉树的注意事项特殊二叉树满二叉树完全二叉树二叉树的性质二叉树的存储形式顺序存储链式存储二叉树链式结构简单初始化二叉树的遍历前序遍历中序遍历后续......
  • 代码随想录算法训练营day10(栈与队列)
    代码随想录算法训练营day10(栈与队列):学习内容:std::queue和std::stack是C++标准库中提供的队列和栈的容器适配器,它们分别基于队列和栈的概念,提供了一组简单的操作接口。std::queuestd::queue是一个先进先出(FIFO)的队列容器适配器。它提供了队列的基本操作,包括入队(pus......
  • cadical基本数据结构分析3——运行状态控制
    在一对文件(options.hpp和options.cpp)运行控制参数统一初始化并设置动态增长规律; 1#ifndef_options_hpp_INCLUDED2#define_options_hpp_INCLUDED34/*------------------------------------------------------------------------*/56//Inorder......
  • 数据结构排序算法之直接插入排序与希尔排序【图文详解】
    P.S.:以下代码均在VS2019环境下测试,不代表所有编译器均可通过。P.S.:测试代码均未展示头文件stdio.h的声明,使用时请自行添加。                                             博主主页:LiUEEEEE         ......
  • [数据结构+二叉树+B-Tree和红黑树与B+Tree与hashMap原理+ concurrentHashMap的原理]析
    目录数据结构:你了解过哪些数据结构:这些数据结构的优缺点:二叉树:特点:二叉树适合做磁盘存储吗: 缺点:B-Tree:b-树的查找过程:思考:特点:B+Tree: B+树搜索过程与B树的查询过程没有区别。但实际上有三点不一样:(B+Tree优势)简述B+Tree:不经历IO的情况下,可以直接......
  • 数据结构与算法
    时间复杂度常数操作包括加减乘除,以及从数组中取出一个值(因为直接计算偏移量,是一块连续的区域)注意:从list中取出一个值不是常数操作,因为需要遍历去找时间复杂度就是计算存在多少个常数操作且忽略低阶项,只要高阶项,且忽略高阶项的系数通过亦或完成交换算法defswap():a......
  • C++数据结构之:栈Stack
    摘要:  it人员无论是使用哪种高级语言开发东东,想要更高效有层次的开发程序的话都躲不开三件套:数据结构,算法和设计模式。数据结构是相互之间存在一种或多种特定关系的数据元素的集合,即带“结构”的数据元素的集合,“结构”就是指数据元素之间存在的关系,分为逻辑结构和存储......
  • 杂数据结构选做
    杂数据结构选做持续更新ing...更新多少取决于我卷了多少似乎都是比较基础的东西,但是我数据结构太菜了,没办法╮(╯_╰)╭#9016.CodeChefMINXORSEG有两种做法,我敲的后一种第一种先不考虑范围问题,考虑现在有三个点\(u,v,w\),若它们的\(lcp\)为\(l\),那么考虑第\(l+1\)位,根据......
  • 数据结构学习笔记-快速排序
    快速排序的算法设计与分析问题描述:设计并分析快速排序【算法设计思想】选择基准值:从待排序数组中选择一个元素作为基准值(pivot)。在这个示例中,选择了数组中的最后一个元素作为基准值。分割数组:将数组分割为两部分,小于等于基准值的元素放在基准值的左边,大于基准值的元素放在右......