数据结构——队列

1.队列

是一种先进先出(FIFO,LILO)的数据结构,它允许在一端进行插入(入队),在另外一端进行删除(出队)

插入(入队):队尾

删除(出队):队头

头指针:指针非彼指针,既可以是整型的数据,也可以是真正的指针,它指向队列的头部

尾指针:指针非彼指针,既可以是整型的数据,也可以是真正的指针,它指向队列的尾部

  • 队列的基本的操作:

    (1)创建队列

    创建顺序队列(常用)

    创建链式队列

    (2)入队

    (3)出队

    (4)判空

    (5)判满

  • 队列是只允许在一端进行插入操作,在另外一端进行操作的线性表。

  • 队列特点:先进先出,后进后出(这种形式称之为:FIFO)

  • 队列的操作:

    1. 入队
    2. 出队
  • 进行插入操作的那一端称之为队尾,进行删除的那一端称之为队头

1、顺序队列

cs 复制代码
//顺序队列
#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、链式队列

cs 复制代码
#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、循环队列

解决假溢出问题,

cs 复制代码
#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、双端队列

是指可以在队列的两端进行插入和删除操作,即一端既可以进行插入也可以进行删除操作,另外一端也是如此

cs 复制代码
#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;
}

这些基本就是队列的一些操作

相关推荐
励志成为嵌入式工程师3 小时前
c语言简单编程练习9
c语言·开发语言·算法·vim
Peter_chq3 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
wheeldown4 小时前
【数据结构】选择排序
数据结构·算法·排序算法
hairenjing11234 小时前
使用 Mac 数据恢复从 iPhoto 图库中恢复照片
windows·stm32·嵌入式硬件·macos·word
hikktn5 小时前
如何在 Rust 中实现内存安全:与 C/C++ 的对比分析
c语言·安全·rust
观音山保我别报错5 小时前
C语言扫雷小游戏
c语言·开发语言·算法
模拟IC攻城狮6 小时前
华为海思招聘-芯片与器件设计工程师-模拟芯片方向- 机试题-真题套题题目——共8套(每套四十题)
嵌入式硬件·华为·硬件架构·芯片
IT B业生6 小时前
51单片机教程(六)- LED流水灯
单片机·嵌入式硬件·51单片机
一枝小雨6 小时前
51单片机学习心得2(基于STC89C52):串口通信(UART)
单片机·嵌入式硬件·51单片机
IT B业生7 小时前
51单片机教程(一)- 开发环境搭建
单片机·嵌入式硬件·51单片机