Loading

队列


返回 我的技术栈(Technology Stack)



队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。

队列是一种先进先出(First In First Out)线性表,简称FIFO。
允许插入的一端称为队尾,允许删除的一端称为队头

image


队列顺序存储

image

循环队列

队列满的条件是:(rear+1)%QueueSize == front
计算队列长度公式:(rear-front+QueueSize)%QueueSize

初始化

#define OK 1		
#define ERROR 0
#define MAXSIZE 5		/*存储空间初始分配量*/

typedef int Status;   /*Status是函数的类型,其值是函数结果状态代码,如ok等*/
typedef int QElemType;

/*循环队列的顺序存储结构*/
typedef struct
{
	QElemType data[MAXSIZE];
	int front;
	int rear;
}SqQueue;

/*初始化一个空队列*/
Status InitQueue(SqQueue* Q)
{
	Q->front = 0;
	Q->rear = 0;
	return OK;
}

队列长度

/*返回Q的元素个数,也就是队列的当前长度*/
Status QueueLength(SqQueue Q)
{
	return (Q.rear - Q.front + MAXSIZE) % MAXSIZE;
}

入队列操作

/*若队列未满,则插入元素e为Q的新的队尾元素*/
Status EnQueue(SqQueue* Q, QElemType e)
{
	if ((Q->rear + 1) % MAXSIZE == Q->front)
		return ERROR; /*队列满的判断*/

	Q->data[Q->rear] = e;  /*将元素e赋值给队尾*/
	Q->rear = (Q->rear + 1) % MAXSIZE;  /*rear指针向后移动一位*/

	return OK;
}

出队列操作

/*若队列未满,则删除Q中队头元素,用e返回其值*/
Status DeQueue(SqQueue* Q, QElemType* e)
{
	if (Q->front == Q->rear)
		return ERROR;  /*队列空的判断*/

	*e = Q->data[Q->front];  /*将队头元素赋值给e*/
	Q->front = (Q->front + 1) % MAXSIZE;  /*front 指针向后移动一位*/

	return OK;
}

队列的链式存储结构

队列的链式存储结构,其实就是线性表的单链表,只不过它只能尾进头出而以,我们把它简称为链队列

image

#include <stdlib.h>
typedef int QElemType;
typedef int Status;   /*Status是函数的类型,其值是函数结果状态代码,如ok等*/

typedef struct QNode  /*结点结构*/
{
	QElemType data;
	struct QNode* next;
}QNode, *QueuePtr;

typedef struct  /*队列的链表结构*/
{
	QueuePtr front, rear; /*队头、队尾指针*/
}LinkQueue;

入队操作

image

/*插入元素e为Q的新队尾元素*/
Status EnQueue(LinkQueue* Q, QElemType e)
{
	QueuePtr  s = (QueuePtr)malloc(sizeof(QNode));
	
	if (!s)
		exit (OVERFLOW);

	s->data = e;
	s->next = NULL; 

	Q->rear->next = s;  /*把拥有元素e的新结点s赋值给原队尾结点的后继, 如图 1  操作*/
	Q->rear = s;  /*把当前的s设置为队尾结点,rear指向s, 如图 2 操作*/

	return OK;
}

出队操作

image

/*若队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR*/
Status DeQueue(LinkQueue* Q, QElemType* e)
{
	QueuePtr p;
	if (Q->front == Q->rear)
		return ERROR;

	p = Q->front->next; /*将要删除的队头元素暂存给 p, 如图 1 操作*/
	*e = p->data;  /*将欲删除的队头结点的值赋值给e*/
	Q->front->next = p->next; /*将原队头结点后继 p->next 赋值给队头结点后继, 如图 2 操作*/

	if (Q->rear == p)  /*如果队头是队尾,则删除后将 rear 指向头结点, 如图 3 操作*/
		Q->rear = Q->front;
	
	free(p);

	return OK;
}

参考:
[1]大话数据结构/程杰著.——北京:清华大学出版社,2011.6


posted @ 2021-08-10 11:24  言非  阅读(107)  评论(0编辑  收藏  举报