队列
队列
1. 基本概念
队列(Queue)是一个重要的数据结构,它具有以下核心特征:
- 是一种线性数据结构
- 遵循先进先出(FIFO)的原则
- 只有两种主要操作:入队(在末尾添加)和出队(从开头删除)
队列的基本结构
一个队列包含以下关键部分:
- 队头(front):最先进入队列的元素位置
- 队尾(rear):最后进入队列的元素位置
- 队列中的元素按顺序排列

2. 实现

共五个程序文件 sequeue.h、linkqueue.h、sequeue.c、linkqueue.c、main.c,包括了顺序队列和链式队列。
sequeue.h
typedef int data_t;
#define N 5 // 队列长度
typedef struct
{
data_t data[N]; // 队列
int front, rear; // 队头、队尾
} sequene_struct, *sequeue;
sequeue sequeue_create(); // 创建队列
int sequeue_clear(sequeue q); // 清空队列
int sequeue_empty(sequeue q); // 判断队列是否为空
int sequeue_full(sequeue q); // 判断队列是否已满
int sequeue_enqueue(sequeue q, data_t x); // 入队
data_t sequeue_dequeue(sequeue q); // 出队
int sequeue_show(sequeue q); // 显示队列
int sequeue_free(sequeue *q); // 释放队列
linkqueue.h
typedef int data_t;
typedef struct node_t
{
data_t data; // 数据域
struct node_t *next; // 指针域
} queuenode_struct, *queuenode; // 队列结点结构体类型定义
typedef struct
{
queuenode front, rear;
} linkqueue_struct,*linkqueue; // 队列结构体类型定义
linkqueue linkqueue_create(); // 创建队列
int linkqueue_empty(linkqueue q); // 判断队列是否为空
int linkqueue_enqueue(linkqueue q, data_t x); // 入队
data_t linkqueue_dequeue(linkqueue q); // 出队
int linkqueue_show(linkqueue q); // 遍历队列
int linkqueue_free(linkqueue *q); // 释放队列
sequeue.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sequeue.h"
/**
* @name sequeue_create()
* @brief 创建顺序队列函数,长度为 N ,初始化数据为 0
* @param 无
* @retval 队列地址
*/
sequeue sequeue_create()
{
// 1. 申请空间给队列
sequeue q = (sequeue)malloc(sizeof(sequene_struct));
if (q == NULL)
{
printf("sequeue create error\n");
}
// 2. 初始化队列
memset(q->data, 0, N*sizeof(data_t));
q->front = q->rear = 0;
return q;
}
/**
* @name sequeue_clear()
* @brief 顺序队列清空函数,长度为 N
* @param q 队列地址
* @retval 0 清空成功, -1 清空失败
*/
int sequeue_clear(sequeue q)
{
// 1. 判断队列是否存在
if (q == NULL)
{
printf("sequeue is invalid\n");
return -1;
}
// 2. 清空队列
q->front = q->rear = 0;
return 0;
}
/**
* @name sequeue_empty()
* @brief 判断队列是否为空
* @param q 队列地址
* @retval 1 队列为空, 0 队列不为空
*/
int sequeue_empty(sequeue q)
{
// 1. 判断队列是否存在
if (q == NULL)
{
printf("sequeue is invalid\n");
return 0;
}
// 2. 判断队列是否为空
return q->front == q->rear ? 1 : 0;
}
/**
* @name sequeue_full()
* @brief 判断队列是否为满
* @param q 队列地址
* @retval 1 队列为满, 0 队列不为满
*/
int sequeue_full(sequeue q)
{
// 1. 判断队列是否存在
if (q == NULL)
{
printf("sequeue is invalid\n");
return 0;
}
// 2. 判断队列是否为满
return q->front == (q->rear+1)%N ? 1 : 0;
}
/**
* @name sequeue_enqueue()
* @brief 入队函数
* @param q 队列地址
* @param x 入队数据
* @retval 0 入队成功, -1 入队失败
*/
int sequeue_enqueue(sequeue q, data_t x)
{
// 1. 判断队列是否存在
if (q == NULL)
{
printf("sequeue is invalid\n");
return -1;
}
// 2. 判断队列是否为满
if (q->front == (q->rear + 1)%N)
{
printf("sequeue is full\n");
return -1;
}
// 3. 入队
q->data[q->rear] = x;
q->rear = (q->rear + 1)%N;
return 0;
}
/**
* @name sequeue_enqueue()
* @brief 入队函数
* @param q 队列地址
* @param x 入队数据
* @retval 0 入队成功, -1 入队失败
*/
data_t sequeue_dequeue(sequeue q)
{
data_t x;
// 1. 判断队列是否存在
if (q == NULL)
{
printf("sequeue is invalid\n");
return -1;
}
// 2. 判断队列是否为空
if (q->front == q->rear)
{
printf("sequeue is empty\n");
return -1;
}
// 3. 出队
x= q->data[q->front];
q->front = (q->front + 1)%N;
return x;
}
/**
* @name sequeue_enqueue()
* @brief 遍历输出队列函数
* @param q 队列地址
* @retval NULL
*/
int sequeue_show(sequeue q)
{
// 1. 判断队列是否存在
if (q == NULL)
{
printf("sequeue is invalid\n");
return -1;
}
// 2. 判断队列是否为空
if (q->front == q->rear)
{
printf("sequeue is empty\n");
return -1;
}
// 3. 遍历队列
if (q->front < q->rear)
{
for (int i = q->front; i < q->rear; i++)
{
printf("%d POS: %d \n", i, q->data[i]);
}
}
else if (q->front > q->rear)
{
for (int i = q->front; i < N; i++)
{
printf("%d POS: %d \n", i, q->data[i]);
}
for (int i = 0; i < q->rear; i++)
{
printf("%d POS: %d \n", i, q->data[i]);
}
}
return 0;
}
int sequeue_free(sequeue *q)
{
// 1. 判断队列是否存在
if (*q == NULL)
{
printf("sequeue is invalid\n");
return -1;
}
// 2. 释放队列
free(*q);
*q = NULL;
return 0;
}
linkqueue.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sequeue.h"
/**
* @name sequeue_create()
* @brief 创建顺序队列函数,长度为 N ,初始化数据为 0
* @param 无
* @retval 队列地址
*/
sequeue sequeue_create()
{
// 1. 申请空间给队列
sequeue q = (sequeue)malloc(sizeof(sequene_struct));
if (q == NULL)
{
printf("sequeue create error\n");
}
// 2. 初始化队列
memset(q->data, 0, N*sizeof(data_t));
q->front = q->rear = 0;
return q;
}
/**
* @name sequeue_clear()
* @brief 顺序队列清空函数,长度为 N
* @param q 队列地址
* @retval 0 清空成功, -1 清空失败
*/
int sequeue_clear(sequeue q)
{
// 1. 判断队列是否存在
if (q == NULL)
{
printf("sequeue is invalid\n");
return -1;
}
// 2. 清空队列
q->front = q->rear = 0;
return 0;
}
/**
* @name sequeue_empty()
* @brief 判断队列是否为空
* @param q 队列地址
* @retval 1 队列为空, 0 队列不为空
*/
int sequeue_empty(sequeue q)
{
// 1. 判断队列是否存在
if (q == NULL)
{
printf("sequeue is invalid\n");
return 0;
}
// 2. 判断队列是否为空
return q->front == q->rear ? 1 : 0;
}
/**
* @name sequeue_full()
* @brief 判断队列是否为满
* @param q 队列地址
* @retval 1 队列为满, 0 队列不为满
*/
int sequeue_full(sequeue q)
{
// 1. 判断队列是否存在
if (q == NULL)
{
printf("sequeue is invalid\n");
return 0;
}
// 2. 判断队列是否为满
return q->front == (q->rear+1)%N ? 1 : 0;
}
/**
* @name sequeue_enqueue()
* @brief 入队函数
* @param q 队列地址
* @param x 入队数据
* @retval 0 入队成功, -1 入队失败
*/
int sequeue_enqueue(sequeue q, data_t x)
{
// 1. 判断队列是否存在
if (q == NULL)
{
printf("sequeue is invalid\n");
return -1;
}
// 2. 判断队列是否为满
if (q->front == (q->rear + 1)%N)
{
printf("sequeue is full\n");
return -1;
}
// 3. 入队
q->data[q->rear] = x;
q->rear = (q->rear + 1)%N;
return 0;
}
/**
* @name sequeue_enqueue()
* @brief 入队函数
* @param q 队列地址
* @param x 入队数据
* @retval 0 入队成功, -1 入队失败
*/
data_t sequeue_dequeue(sequeue q)
{
data_t x;
// 1. 判断队列是否存在
if (q == NULL)
{
printf("sequeue is invalid\n");
return -1;
}
// 2. 判断队列是否为空
if (q->front == q->rear)
{
printf("sequeue is empty\n");
return -1;
}
// 3. 出队
x= q->data[q->front];
q->front = (q->front + 1)%N;
return x;
}
/**
* @name sequeue_enqueue()
* @brief 遍历输出队列函数
* @param q 队列地址
* @retval NULL
*/
int sequeue_show(sequeue q)
{
// 1. 判断队列是否存在
if (q == NULL)
{
printf("sequeue is invalid\n");
return -1;
}
// 2. 判断队列是否为空
if (q->front == q->rear)
{
printf("sequeue is empty\n");
return -1;
}
// 3. 遍历队列
if (q->front < q->rear)
{
for (int i = q->front; i < q->rear; i++)
{
printf("%d POS: %d \n", i, q->data[i]);
}
}
else if (q->front > q->rear)
{
for (int i = q->front; i < N; i++)
{
printf("%d POS: %d \n", i, q->data[i]);
}
for (int i = 0; i < q->rear; i++)
{
printf("%d POS: %d \n", i, q->data[i]);
}
}
return 0;
}
int sequeue_free(sequeue *q)
{
// 1. 判断队列是否存在
if (*q == NULL)
{
printf("sequeue is invalid\n");
return -1;
}
// 2. 释放队列
free(*q);
*q = NULL;
return 0;
}
mian.c
#include <stdio.h>
#include "sequeue.h"
#include "linkqueue.h"
void test_sequeue();
void test_linkqueue();
int main()
{
test_sequeue();
test_linkqueue();
return 0;
}
void test_linkqueue()
{
printf("******test_linkqueue*****\n");
linkqueue q = linkqueue_create();
linkqueue_enqueue(q, 10);
linkqueue_enqueue(q, 90);
linkqueue_enqueue(q, 30);
linkqueue_show(q);
linkqueue_enqueue(q, 10);
linkqueue_enqueue(q, 90);
linkqueue_enqueue(q, 30);
printf("linkqueue_dequeue = %d\n", (int)linkqueue_dequeue(q));
printf("linkqueue_dequeue = %d\n", (int)linkqueue_dequeue(q));
linkqueue_enqueue(q, 33);
linkqueue_enqueue(q, 55);
linkqueue_enqueue(q, 99);
linkqueue_show(q);
printf("linkqueue_dequeue = %d\n", (int)linkqueue_dequeue(q));
printf("linkqueue_dequeue = %d\n", (int)linkqueue_dequeue(q));
linkqueue_show(q);
linkqueue_free(&q);
return;
}
void test_sequeue()
{
printf("******_test_sequeue_*****\n");
sequeue q = sequeue_create();
sequeue_enqueue(q, 10);
sequeue_enqueue(q, 90);
sequeue_enqueue(q, 30);
sequeue_show(q);
sequeue_clear(q);
printf("sequeue_empty(q) = %d\n", sequeue_empty(q));
sequeue_enqueue(q, 10);
sequeue_enqueue(q, 90);
sequeue_enqueue(q, 30);
printf("sequeue_dequeue = %d\n", (int)sequeue_dequeue(q));
printf("sequeue_dequeue = %d\n", (int)sequeue_dequeue(q));
sequeue_enqueue(q, 33);
sequeue_enqueue(q, 55);
sequeue_enqueue(q, 99);
sequeue_show(q);
sequeue_free(&q);
return;
}

浙公网安备 33010602011771号