1.队列
是一种先进先出(FIFO,LILO)的数据结构,它允许在一端进行插入(入队),在另外一端进行删除(出队)
插入(入队):队尾
删除(出队):队头
头指针:指针非彼指针,既可以是整型的数据,也可以是真正的指针,它指向队列的头部
尾指针:指针非彼指针,既可以是整型的数据,也可以是真正的指针,它指向队列的尾部
-
队列的基本的操作:
(1)创建队列
创建顺序队列(常用)
创建链式队列
(2)入队
(3)出队
(4)判空
(5)判满
- 队列是只允许在一端进行插入操作,在另外一端进行操作的线性表。
- 队列特点:先进先出,后进后出(这种形式称之为:FIFO)
- 队列的操作:
- 入队
- 出队
- 进行插入操作的那一端称之为队尾,进行删除的那一端称之为队头
1、顺序队列
//顺序队列
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<string.h>
#define MAX 20
struct queue
{
int queue[MAX];
int head;//头指针
int tail;//尾指针
};
//创建队列
struct queue *Queue_creat()
{
struct queue*P=(struct queue*)malloc(sizeof(struct queue));
if(P==NULL)
{
printf("创建队列失败\n");
return NULL;
}
memset(P->queue,0,sizeof(P->queue));
P->head=0;
P->tail=0;
return P;
}
//判空
bool Queue_Empty(struct queue *P)
{
if(P->head==P->tail)
{
printf("队列为空\n");
return true;
}
return false;
}
//判满
bool Queue_Full(struct queue*P)//这里有假溢出的情况,所以使用队列时一般使用循环队列
{
if(P->tail==MAX-1)
{
printf("队列已满\n");
return true;
}
return false;
}
//入队
bool Queue_Insert(struct queue*P,int value)
{
if(Queue_Full(P))
{
printf("队列已满,入队失败\n");
return false;
}
struct queue*node=P;
node->queue[node->tail]=value;
node->tail++;
return true;
}
//出队
bool Queue_Out(struct queue*P,int *value)
{
if(Queue_Empty(P))
{
printf("队列为空,出队失败\n");
return false;
}
struct queue*node=P;
*value=node->queue[P->head];
node->queue[P->head]=0;//出队之后,将出队的元素赋值为0
P->head++;
return true;
};
int main(int argc, const char *argv[])
{
int value;
struct queue *P=Queue_creat();
Queue_Insert(P,1);
Queue_Insert(P,2);
Queue_Insert(P,3);
Queue_Insert(P,4);
Queue_Insert(P,5);
Queue_Out(P,&value);
printf("value=%d\n",value);
Queue_Out(P,&value);
printf("value=%d\n",value);
return 0;
}
2、链式队列
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// 定义结点
struct node {
int data; // 数据域
struct node *next; // 指针域
};
// 定义队列指针
struct queue {
struct node *head; // 头指针
struct node *tail; // 尾指针
};
// 创建队列
struct queue *Queue_create() {
struct queue *queue = (struct queue *)malloc(sizeof(struct queue));
if (queue == NULL) {
printf("创建队列失败\n");
return NULL;
}
queue->head = queue->tail = NULL;
return queue;
}
// 判空
bool Queue_Empty(struct queue *queue) {
return queue->head == NULL;
}
// 入队
bool Queue_Insert(struct queue *queue, int value) {
struct node *node = (struct node *)malloc(sizeof(struct node));
if (node == NULL) {
printf("创建结点失败\n");
return false;
}
node->data = value;
node->next = NULL;
if (Queue_Empty(queue)) {
queue->head = queue->tail = node;
} else {
queue->tail->next = node;
queue->tail = node;
}
return true;
}
// 出队
bool Queue_Out(struct queue *queue, int *value) {
if (Queue_Empty(queue)) {
printf("队列为空,出队失败\n");
return false;
}
struct node *temp = queue->head;
*value = temp->data;
queue->head = queue->head->next;
if (queue->head == NULL) { // 如果队列为空
queue->tail = NULL;
}
free(temp);
return true;
}
int main(int argc, const char *argv[]) {
int value;
struct queue *P = Queue_create();
if (P == NULL) return -1;
Queue_Insert(P, 1);
Queue_Insert(P, 2);
Queue_Insert(P, 3);
Queue_Insert(P, 4);
Queue_Insert(P, 5);
if (Queue_Out(P, &value)) {
printf("value=%d\n", value);
}
if (Queue_Out(P, &value)) {
printf("value=%d\n", value);
}
// 释放队列内存
while (!Queue_Empty(P)) {
Queue_Out(P, &value);
}
free(P);
return 0;
}
3、循环队列
解决假溢出问题,
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// 定义队列的最大长度
#define MAX_SIZE 5
// 定义循环队列结构
struct CircularQueue {
int data[MAX_SIZE]; // 队列数组
int front; // 队头指针
int rear; // 队尾指针
};
// 创建循环队列
struct CircularQueue* createQueue() {
struct CircularQueue *queue = (struct CircularQueue *)malloc(sizeof(struct CircularQueue));
if (queue == NULL) {
printf("内存分配失败\n");
return NULL;
}
queue->front = queue->rear = 0; // 初始化队头和队尾指针
return queue;
}
// 判空
bool isEmpty(struct CircularQueue *queue) {
return queue->front == queue->rear;
}
// 判满
bool isFull(struct CircularQueue *queue) {
return (queue->rear + 1) % MAX_SIZE == queue->front;
}
// 入队
bool enqueue(struct CircularQueue *queue, int value) {
if (isFull(queue)) {
printf("队列已满,入队失败\n");
return false;
}
queue->data[queue->rear] = value;
queue->rear = (queue->rear + 1) % MAX_SIZE; // 更新队尾指针
return true;
}
// 出队
bool dequeue(struct CircularQueue *queue, int *value) {
if (isEmpty(queue)) {
printf("队列为空,出队失败\n");
return false;
}
*value = queue->data[queue->front];
queue->front = (queue->front + 1) % MAX_SIZE; // 更新队头指针
return true;
}
// 获取队列中的元素个数
int queueSize(struct CircularQueue *queue) {
return (queue->rear - queue->front + MAX_SIZE) % MAX_SIZE;
}
// 打印队列中的元素
void printQueue(struct CircularQueue *queue) {
if (isEmpty(queue)) {
printf("队列为空\n");
return;
}
int i = queue->front;
while (i != queue->rear) {
printf("%d ", queue->data[i]);
i = (i + 1) % MAX_SIZE;
}
printf("\n");
}
int main() {
struct CircularQueue *queue = createQueue();
enqueue(queue, 1);
enqueue(queue, 2);
enqueue(queue, 3);
enqueue(queue, 4);
printQueue(queue); // 输出: 1 2 3 4
int value;
dequeue(queue, &value);
printf("出队元素: %d\n", value); // 输出: 1
enqueue(queue, 5);
enqueue(queue, 6); // 队列满,无法插入
printQueue(queue); // 输出: 2 3 4 5
return 0;
}
4、双端队列
是指可以在队列的两端进行插入和删除操作,即一端既可以进行插入也可以进行删除操作,另外一端也是如此
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_SIZE 5 // 双端队列的最大容量
// 定义双端队列结构
struct Deque {
int data[MAX_SIZE]; // 队列数组
int front; // 队头指针
int rear; // 队尾指针
};
// 创建双端队列
struct Deque* createDeque() {
struct Deque *deque = (struct Deque *)malloc(sizeof(struct Deque));
if (deque == NULL) {
printf("内存分配失败\n");
return NULL;
}
deque->front = 0;
deque->rear = 0;
return deque;
}
// 判空
bool isEmpty(struct Deque *deque) {
return deque->front == deque->rear;
}
// 判满
bool isFull(struct Deque *deque) {
return (deque->rear + 1) % MAX_SIZE == deque->front;
}
// 从队头插入元素
bool insertFront(struct Deque *deque, int value) {
if (isFull(deque)) {
printf("队列已满,无法从队头插入\n");
return false;
}
deque->front = (deque->front - 1 + MAX_SIZE) % MAX_SIZE;
deque->data[deque->front] = value;
return true;
}
// 从队尾插入元素
bool insertRear(struct Deque *deque, int value) {
if (isFull(deque)) {
printf("队列已满,无法从队尾插入\n");
return false;
}
deque->data[deque->rear] = value;
deque->rear = (deque->rear + 1) % MAX_SIZE;
return true;
}
// 从队头删除元素
bool deleteFront(struct Deque *deque, int *value) {
if (isEmpty(deque)) {
printf("队列为空,无法从队头删除\n");
return false;
}
*value = deque->data[deque->front];
deque->front = (deque->front + 1) % MAX_SIZE;
return true;
}
// 从队尾删除元素
bool deleteRear(struct Deque *deque, int *value) {
if (isEmpty(deque)) {
printf("队列为空,无法从队尾删除\n");
return false;
}
deque->rear = (deque->rear - 1 + MAX_SIZE) % MAX_SIZE;
*value = deque->data[deque->rear];
return true;
}
// 打印双端队列中的元素
void printDeque(struct Deque *deque) {
if (isEmpty(deque)) {
printf("队列为空\n");
return;
}
int i = deque->front;
while (i != deque->rear) {
printf("%d ", deque->data[i]);
i = (i + 1) % MAX_SIZE;
}
printf("\n");
}
int main() {
struct Deque *deque = createDeque();
insertRear(deque, 1);
insertRear(deque, 2);
insertFront(deque, 3);
insertFront(deque, 4);
printDeque(deque); // 输出: 4 3 1 2
int value;
deleteFront(deque, &value);
printf("从队头删除元素: %d\n", value); // 输出: 4
deleteRear(deque, &value);
printf("从队尾删除元素: %d\n", value); // 输出: 2
printDeque(deque); // 输出: 3 1
// 测试队列满的情况
insertRear(deque, 5);
insertRear(deque, 6);
if (!insertRear(deque, 7)) {
printf("无法插入元素7,因为队列已满\n");
}
printDeque(deque); // 输出: 3 1 5 6
return 0;
}
这些基本就是队列的一些操作