【数据结构】14 队列(带头结点的链式存储和顺序存储实现)

定义

队列是一个有序线性表,但是队列的插入、删除操作是分别在线性表的两个不同端点进行的。

设一个队列 Q = ( a 1 , a 2 , . . . , a n ) Q = (a_1, a_2,...,a_n) Q=(a1,a2,...,an),那么 a 1 a_1 a1被称为队头元素, a n a_n an为队尾元素。假如将元素A,B,C,D依次插入队列,第一个从队列中删除的元素为A,即先插入的将被先删除,故队列也称为先进先出表。

抽象数据类型
类型名称 :队列
数据对象集 :一个有0个或者多个元素的有穷线性表
操作集 :对于一个长度为正整数MaxSize的队列 Q Q Q, 记队列中的任一元素 X X X,队列的基本操作集为:

  1. Queue CreateQueue(int MaxSize)
  2. bool IsFull(Queue Q)
  3. bool AddQ(Queue Q, ElementType X)
  4. bool Is Empty(Queue Q)
  5. ElementType DeleteQ(Queue Q)

队列的顺序存储实现

队列的最简单的表示方法是用数组。用数组存储队列有许多具体的方法。一般可以选择将队列头放数组下标小的位置,而将队列尾放在数组下标大的位置,并用两个变量Front和Rear分别指示队列的头和尾。一般把Front和Rear先初始化为-1。当有元素入队时,Rear向右移动一格,放入队尾元素;当有元素出队时,先将Front向右移动一格,再删除队首元素。

随着入队出队的进行会使整个队列整体向后移动这样就出现了如上图所示的现象,指针已经移到了最后,在再有元素入队时就会出现溢出,可是事实上此时队中并未真的满员,这种现象称为假溢出。

为了解决队尾溢出而实际上数组中仍有空余空间的问题,一般在队列的顺序存储结构中采用循环队列的方式,队尾指针和队首指针到达数组端点时能折回到数组开始处即相当于将数组头尾相接想象成环形,如图所示当插入和删除操作的作用单元达到数组的末端后用公式"Rear % 数组长度"取余运算就可以实现折返到起始单元。

队列初始化时,将Front和Rear都初始化为0,当插入一个元素时,Rear+1,删除一个元素时,Front加一。

当Front = Rear时,队列为空。

当队尾指针加1就会从后面赶上头指针,(Rear + 1)%数组长度 = Front

代码实现

顺序存储

数据结构

c 复制代码
typedef int ElementType;
typedef int Position;
typedef struct QNode* PtrToQNode;
struct QNode {
	ElementType* Data;
	Position Front, Rear;
	int MaxSize;
};
typedef PtrToQNode Queue;

创建循环队列

c 复制代码
Queue CreateQueue(int MaxSize) {
	Queue Q = (Queue)malloc(sizeof(struct QNode));
	Q->MaxSize = MaxSize;
	Q->Data = (ElementType*)malloc(sizeof(ElementType) * MaxSize);
	Q->Front = 0;
	Q->Rear = 0;
	return Q;
}

插入元素

c 复制代码
bool IsFull(Queue Q) {
	if ((Q->Rear + 1) % Q->MaxSize == Q->Front) {
		return true;
	}
	else {
		return false;
	}
}

bool AddQ(Queue Q, ElementType X) {
	if (IsFull(Q)) {
		printf("The Queue is full!\n");
		return false;
	}
	else {
		Q->Rear = (Q->Rear + 1) % Q->MaxSize;
		Q->Data[Q->Rear] = X;
		return true;
	}
}

删除元素

c 复制代码
bool IsEmpty(Queue Q) {
	if (Q->Rear == Q->Front) {
		return true;
	}
	else {
		return false;
	}
}


ElementType DeleteQ(Queue Q) {
	if (IsEmpty(Q)) {
		printf("The Queue is empty!\n");
		return -1;
	}
	else {
		Q->Front = (Q->Front + 1) % (Q->MaxSize);
		return Q->Data[(Q->Front)];


	}
}

完整代码

c 复制代码
# include <stdio.h>
#include < stdlib.h>
#include <ctype.h>
#include <string.h>

typedef int ElementType;
typedef int Position;
typedef struct QNode* PtrToQNode;
struct QNode {
	ElementType* Data;
	Position Front, Rear;
	int MaxSize;
};
typedef PtrToQNode Queue;


Queue CreateQueue(int MaxSize) {
	Queue Q = (Queue)malloc(sizeof(struct QNode));
	Q->MaxSize = MaxSize;
	Q->Data = (ElementType*)malloc(sizeof(ElementType) * MaxSize);
	Q->Front = 0;
	Q->Rear = 0;
	return Q;
}

bool IsFull(Queue Q) {
	if ((Q->Rear + 1) % Q->MaxSize == Q->Front) {
		return true;
	}
	else {
		return false;
	}
}


bool AddQ(Queue Q, ElementType X) {
	if (IsFull(Q)) {
		printf("The Queue is full!\n");
		return false;
	}
	else {
		Q->Rear = (Q->Rear + 1) % Q->MaxSize;
		Q->Data[Q->Rear] = X;
		return true;
	}
}


void printQ(Queue Q) {
	int f = Q->Front;
	int r = Q->Rear;
	while (f != r) {
		f = (f + 1) % (Q->MaxSize);
		printf("QNode: %d\n", Q->Data[f]);
	}
}

bool IsEmpty(Queue Q) {
	if (Q->Rear == Q->Front) {
		return true;
	}
	else {
		return false;
	}
}


ElementType DeleteQ(Queue Q) {
	if (IsEmpty(Q)) {
		printf("The Queue is empty!\n");
		return -1;
	}
	else {
		Q->Front = (Q->Front + 1) % (Q->MaxSize);
		return Q->Data[(Q->Front)];


	}
}

int main() {

	Queue Q = CreateQueue(10);
	ElementType X;
	int N;
	scanf_s("%d", &N);
	while (N--) {
		scanf_s("%d", &X);
		if (AddQ(Q, X) == false) {
			printf("Add error!\n");
		}

	}

	printQ(Q);
	while (!IsEmpty(Q)) {
		ElementType out = DeleteQ(Q);
		printf("Out : %d\n", out);
		printf("\n");
		printQ(Q);
	}
	



}

链式存储

队列的头必须指向的是队列的头结点,队尾指向链表的尾节点

数据结构

c 复制代码
typedef int ElementType;
typedef struct Node* PtrToNode;
struct Node {
	ElementType Data;
	PtrToNode Next;
};

typedef struct Node* Position;

struct QNode {
	Position Rear, Front;
	int MaxSize;
};
typedef struct QNode * Queue;

队列的创建

c 复制代码
Queue CreateQueue(int MaxSize) {
	Queue Q = (Queue)malloc(sizeof(struct QNode));
	Q->MaxSize = MaxSize;
	PtrToNode L = (PtrToNode)malloc(sizeof(struct Node));
	
	L->Next = NULL;
	Q->Front = L;
	Q->Rear = L;

	
	printf("finish!\n");

	return Q;


}

加入元素

c 复制代码
bool IsFull(Queue Q) {
	int cnt = 0;
	
	Position t = Q->Front;
	
	while (t != Q->Rear) {
		t = t->Next;
		cnt++;
	}
	printf("cnt : %d\n", cnt);
	if (cnt == Q->MaxSize) {
		return true;
	}
	else {
		return false;
	}
}


bool AddQ(Queue Q, ElementType X) {
	if (IsFull(Q)) {
		printf("The Queue is full!\n");
		return false;
	}

	Position R = Q->Rear;
	while (R->Next != NULL) {
		R = R->Next;
	}
	PtrToNode t = (PtrToNode)malloc(sizeof(struct Node));
	t->Data = X;
	t->Next = R->Next;
	R->Next = t;
	Q->Rear = t;

	return true;


}

删除元素

c 复制代码
bool IsEmpty(Queue Q) {
	if (Q->Front->Next == NULL) {
		return true;
	}
	else {
		return false;
	}
}

ElementType DeleteQ(Queue Q) {
	if(IsEmpty(Q)) {
		printf("The Queue is empty!\n");
		return -1;
	}
	else {

		ElementType t = Q->Front->Next->Data;
		Position te = Q->Front;
		Q->Front->Next = Q->Front->Next->Next;
		return t;
	}
}

完整代码

c 复制代码
# include <stdio.h>
#include < stdlib.h>
#include <ctype.h>
#include <string.h>

typedef int ElementType;
typedef struct Node* PtrToNode;
struct Node {
	ElementType Data;
	PtrToNode Next;
};

typedef struct Node* Position;

struct QNode {
	Position Rear, Front;
	int MaxSize;
};
typedef struct QNode * Queue;


Queue CreateQueue(int MaxSize) {
	Queue Q = (Queue)malloc(sizeof(struct QNode));
	Q->MaxSize = MaxSize;
	PtrToNode L = (PtrToNode)malloc(sizeof(struct Node));
	
	L->Next = NULL;
	Q->Front = L;
	Q->Rear = L;

	
	printf("finish!\n");

	return Q;


}

bool IsFull(Queue Q) {
	int cnt = 0;
	
	Position t = Q->Front;
	
	while (t != Q->Rear) {
		t = t->Next;
		cnt++;
	}
	printf("cnt : %d\n", cnt);
	if (cnt == Q->MaxSize) {
		return true;
	}
	else {
		return false;
	}
}


bool AddQ(Queue Q, ElementType X) {
	if (IsFull(Q)) {
		printf("The Queue is full!\n");
		return false;
	}

	Position R = Q->Rear;
	while (R->Next != NULL) {
		R = R->Next;
	}
	PtrToNode t = (PtrToNode)malloc(sizeof(struct Node));
	t->Data = X;
	t->Next = R->Next;
	R->Next = t;
	Q->Rear = t;

	return true;


}

void printq(Queue Q) {
	Position t = Q->Front;
	while (t != Q->Rear)
	{
		t = t->Next;
		printf("QNode: %d\n", t->Data);
	}

}

bool IsEmpty(Queue Q) {
	if (Q->Front->Next == NULL) {
		return true;
	}
	else {
		return false;
	}
}

ElementType DeleteQ(Queue Q) {
	if(IsEmpty(Q)) {
		printf("The Queue is empty!\n");
		return -1;
	}
	else {

		ElementType t = Q->Front->Next->Data;
		Position te = Q->Front;
		Q->Front->Next = Q->Front->Next->Next;
		return t;
	}
}

int main() {

	Queue Q = CreateQueue(10);

	ElementType X;
	int N;
	scanf_s("%d", &N);
	while (N--) {
		scanf_s("%d", &X);
		if (AddQ(Q, X) == false) {
			printf("Add error!\n");
		}

	}

	printq(Q);
	while (!IsEmpty(Q)) {
		int out = DeleteQ(Q);
		printf("\n");
		printf("Out : %d\n", out);
		//printq(Q);
	}
	


}
相关推荐
hansang_IR6 小时前
【题解】LC:倍增 / 区间并查集(Range Parallel Unionfind)
c++·算法·并查集
Tisfy7 小时前
LeetCode 3731.找出缺失的元素:哈希 / 排序
算法·leetcode·哈希算法·排序·哈希表
lucas_AI7 小时前
Q-CueGraph:你的多模态大模型会 zoom,但真的知道该看哪儿吗?
人工智能·算法
kaixin_啊啊8 小时前
test_机器学习算法学习
学习·算法·机器学习
liulilittle8 小时前
MOE路由:路由(logits: top-k/8)
c++·人工智能·算法·机器学习·llm
旖旎夜光8 小时前
LeetCode 11:盛最多水的容器(双指针问题) —— 题解
数据结构·c++·算法·leetcode·双指针
一只齐刘海的猫8 小时前
【Leetcode】乘积最大子数组
算法·leetcode·职场和发展
余生皆假期-9 小时前
傅里叶变换和拉普拉斯变换
人工智能·算法·机器学习
不一样的故事1269 小时前
芯片设计是一个高度复杂、分工精细的系统工程
数据结构·经验分享
数模竞赛Paid answer10 小时前
2026年五一杯数学建模C题边坡预警问题求解全过程文档及程序
算法·数学建模·五一杯