队列Queue
队列也是一种操作受限的线性表,只允许在表的一端进行插入,而在表的另一端进行删除。他的特点是:先进先出
逻辑结构如下:
一、队列的顺序存储结构
队列的顺序存储结构是指分配一块连续的内存单元存放队列中的元素,并有两个指针:队头指针front指向队头元素,队尾指针rear指向队尾元素的下一个位置。(不同的书可能front和rear的指向不同,不过都大同小异)
高频考点:
- 队列元素的个数:(rear-front+MaxSize)% MaxSize
- 队列已满条件:
- 顺序存储:(rear+1)%MaxSize == front
- 链式存储:一般不会满,除非内存不足
代码实现:
1、定义和初始化:
#include<stdio.h>
#define MaxSize 10
typedef struct {
int data[MaxSize];//使用静态数组存放指针
int front;//队头指针和队尾指针
int rear;
}SqQueue;
//初始化:
void InitQueue(SqQueue& Q) {
Q.rear = Q.front = 0;
}
2、判满和入队:
//判满
bool QueueFull(SqQueue Q) {
if ((Q.rear + 1) % MaxSize == Q.front) {
return true;
}
return false;
}
//入队
bool EnQueue(SqQueue& Q, int e) {
//判满
if(QueueFull(Q)){
return false;
}
Q.data[Q.rear] = e;
Q.rear = (Q.rear + 1) % MaxSize;
return true;
}
3、判空和出队:
//判空
bool QueueEmpty(SqQueue Q) {
if (Q.rear == Q.front) {
return true;
}
return false;
}
//出队
bool DeQueue(SqQueue& Q, int& e) {
//判空
if(QueueEmpty(Q)){
return false;
}
e = Q.data[Q.front];
Q.front = (Q.front + 1) % MaxSize;
return true;
}
二、队列的链式存储
队列的链式表示称为链队列,他实际上是一个同时带有队头指针和队尾指针的单链表。头指针指向队头结点,尾指针指向队尾结点,即单链表最后一个节点。
代码实现
1、定义和初始化
#include<stdlib.h>
//链式队列结点
typedef struct LNode {
int data;
struct LNode *next;
};
//链式队列
typedef struct {
//队列的队头和队尾指针
LNode *front, * rear;
}LQueue;
//带头结点初始化:
void InitQueue(LQueue& Q) {
LNode* head = (LNode*)malloc(sizeof(LNode));
head->next = NULL;
Q.front = head;
Q.rear = head;
}
//不带头初始化:
void InitQueue1(LQueue& Q) {
Q.front = NULL;
Q.rear = NULL;
}
2、判空
//带头判空:
bool QueueEmpty(LQueue Q) {
if (Q.front == Q.rear) {
return true;
}
return false;
}
//不带头判空:
bool QueueEmpty1(LQueue Q) {
if (Q.front == NULL) {
return true;
}
return false;
}
3、入队
//带头入队:
bool EnQueue(LQueue Q,int e) {
LNode* node = (LNode*)malloc(sizeof(LNode));
node->data = e;
node->next = NULL;
Q.rear->next = node;
Q.rear = node;
return true;
}
//不带头入队
bool EnQueue1(LQueue Q, int e) {
LNode* node = (LNode*)malloc(sizeof(LNode));
node->data = e;
node->next = NULL;
//先判断是不是空的:
if (QueueEmpty1(Q)) {
Q.rear = node;
Q.front = node;
return true;
}
//不空的话
Q.rear->next = node;
Q.rear = node;
return true;
}
4、出队
//带头出队:
bool DeQueue(LQueue& Q, int& x) {
//判空
if (QueueEmpty(Q)) {
return false;
}
//不空的话
x = Q.front->data;
LNode* node = (LNode*)malloc(sizeof(LNode));
node = Q.front->next;
Q.front->next = node->next;
//判断是否是最后一个节点出队
if (Q.rear == node) {
Q.rear = Q.front;
}
free(node);
}
//不带头出队
bool DeQueue1(LQueue& Q, int& x) {
//判空
if (QueueEmpty1(Q)) {
return false;
}
//不空的话
x = Q.front->data;
LNode* node = (LNode*)malloc(sizeof(LNode));
node = Q.front->next;
Q.front->next = node->next;
//判断是否是最后一个节点出队
if (Q.rear == node) {
Q.rear = NULL;
Q.front = NULL;
}
free(node);
}