1. 队列
// 3.2 队列
// 3.2.1 队列的基本概念
// 1. 队列的定义
// 定义:一种操作受限的线性表,只允许在表的一端(队尾Rear)进行插入,而在表的另一端(队头Front)进行删除。
// 操作特性:先进先出(First In First Out)
// 2. 队列常见的基本操作
// InitQueue(&Q)
// QueueEmpty(Q)
// EnQueue(&Q, x)
// DeQueue(&Q, &x)
// GetHead(Q, &x)
// 3.2.2 队列的顺序存储结构
// 1. 队列的顺序存储
// 顺序存储类型:
// #define MaxSize 50
// typedef struct {
// ElemType data[MaxSize];
// int front, rear;
// }SqQueue;
// 初始状态(队空条件):Q.front == Q.rear == 0
// 进队:队不满时,先送值到队尾元素,再将队尾指针加1
// 出队:队不空时,先取队头元素值,再将队头指针加1
// 2. 循环队列
// 定义:将顺序队列臆造为一个环状的空间,即把存储队列元素的表从逻辑上视为一个环,称为循环队列
// 初始时,Q.front = Q.rear = 0;
// 队首指针进1: Q.front = (Q.front + 1) % MaxSize
// 队尾指针进1: Q.rear = (Q.rear + 1) % MaxSize
// 队列长度: (Q.rear + MaxSize - Q.front) % MaxSize
// 出队入队时:指针都按顺时针方向进1
// 队满条件:牺牲一个单元,队头指针在队尾指针的下一位置作为队满的标志(Q.rear + 1)% MaxSize == Q.front
// 3. 循环队列的操作
// InitQueue(SqQueue &Q)
// IsEmpty(SqQueue Q)
// EnQueue(SqQueue &Q, ElemType x)
// DeQueue(SqQueue &Q, ElemType &x)
// 4. 为什么引入循环队列
// 顺序队列中的溢出现象:
// 1)下溢,队空时做出队运算产生的溢出现象
// 2)真上溢,队满时做出队运算产生的溢出现象
// 3)假上溢,由于入队和出队操作中,头尾指针只增加不减小,致使被删元素的空间永远无法重新利用。当队列中实际的元素个数远远小于向量空间的规模时,
// 也可能由于尾指针已超过向量空间的上限而不能做入队操作。
// 于是,为了充分利用向量空间,克服“假上溢”现象,引入了循环队列
// 3.2.3 队列的链式存储结构
// 1. 队列的链式存储
// 链队列:一个同时带有队头指针和队尾指针的单链表
// 队列的链式存储类型:
// 结点
// typedef struct{
// ElemType data;
// struct LinkNode *next;
// }LinkNode;
// 链式队列
// typedef struct{
// LinkNode *front, *rear;
// }LinkQueue;
// 2. 链式队列的基本操作
// InitQueue()
// IsEmpty(SqQueue Q)
// EnQueue(SqQueue &Q, ElemType x)
// DeQueue(SqQueue &Q, ElemType &x)
// 3. 链式队列适用场景
// 1)适合数据元素变动比较大的情形,且不存在因队列满而产生溢出的问题。
// 2)程序中需要使用多个队列时,使用链式队列就不会出现存储分配不合理和溢出问题。
// 3.2.4 双端队列
// 双端队列:允许两端都可以进行入队和出队操作的队列
// 输出受限的双端队列:允许在一端进行插入和删除,但在另一端只允许插入的双端队列
// 输入受限的双端队列:允许在一端进行插入和删除,但在另一端只允许删除的双端队列
2. 循环队列基本操作
#include<stdio.h>
#define MaxSize 10
#define ElemType int
typedef struct {
ElemType data[MaxSize];
int front, rear;
}SqQueue;
// 初始化
void InitQueue(SqQueue &Q) {
Q.front = Q.rear = 0;
}
// 判空
bool IsEmpty(SqQueue Q) {
return Q.rear == Q.front == 0;
}
// 队满
bool IsFull(SqQueue Q) {
return (Q.rear + 1) % MaxSize == Q.front;
}
// 进队
void EnQueue(SqQueue &Q, ElemType x) {
if(IsFull(Q)) {
printf("队满,无法进队");
return;
}
Q.data[Q.rear] = x;
Q.rear = (Q.rear + 1) % MaxSize;
}
// 出队
void DeQueue(SqQueue &Q, ElemType &x) {
if(IsEmpty(Q)) {
printf("队空,无法出队");
return;
}
x = Q.data[Q.front];
Q.front = (Q.front + 1) % MaxSize;
}
int main() {
return 0;
}
3. 链式队列基本操作
#include<stdio.h>
#include<stdlib.h>
#define ElemType int
typedef struct LinkNode{
ElemType data;
struct LinkNode *next;
}LinkNode;
typedef struct{
LinkNode *front, *rear;
}LinkQueue;
// 初始化
void InitQueue(LinkQueue &Q) {
Q.front = Q.rear = (LinkNode*)malloc(sizeof(LinkNode));
Q.front->next = NULL;
}
// 判空
bool IsEmpty(LinkQueue Q) {
return Q.front == Q.rear;
}
// 入队
void EnQueue(LinkQueue &Q, ElemType x) {
LinkNode *s = (LinkNode*)malloc(sizeof(LinkNode));
s->data = x;
s->next = NULL;
Q.rear->next = s;
Q.rear = s;
}
// 出队
void DeQueue(LinkQueue &Q, ElemType &x) {
if(IsEmpty(Q)) {
printf("队空,无法出队");
return;
}
LinkNode *p = Q.front->next;
x = p->data;
Q.front->next = p->next;
// if(p == Q.rear) {
// int test1 = Q.front->next == NULL ? 1 : 0;
// int test2 = Q.rear->next == NULL ? 1 : 0;
// printf("%d %d %d %d \n", test1, test2, Q.front->data, Q.rear->data);
// Q.front = Q.rear;
// printf("%d %d \n", Q.front->data, Q.rear->data);
// }
if(Q.rear == p) {
// int test1 = Q.front->next == NULL ? 1 : 0;
// int test2 = Q.rear->next == NULL ? 1 : 0;
// printf("%d %d %d %d \n", test1, test2, Q.front->data, Q.rear->data);
Q.rear = Q.front;
// printf("%d %d \n", Q.front->data, Q.rear->data);
}
free(p);
}
// 输出队列
void printQueue(LinkQueue Q) {
if (IsEmpty(Q)) {
printf("队空");
return;
}
LinkNode *p = Q.front->next;
while(p) {
printf("%d ", p->data);
p = p->next;
}
}
int main() {
LinkQueue Q;
ElemType x;
printf("----------初始化----------\n");
InitQueue(Q);
printf("----------入队----------\n");
printf("请输入入队元素值:");
scanf("%d", &x);
EnQueue(Q, x);
printf("----------当前队列----------\n");
printQueue(Q);
printf("\n");
printf("----------出队----------\n");
DeQueue(Q, x);
printf("----------当前队列----------\n");
printQueue(Q);
printf("\n");
return 0;
}