简介
- 队列也是一种数据结构,队列也可以用来存放数字
- 每次只能向队列里将入一个数字,每次只能从队列里获得一个数字
- 在队列中,允许插入的一段称为入队口,允许删除的一段称为出队口
- 它的原则是先进先出(FIFO: first in first out),先进入队列的数据先出去,后进入的后出去。
- 队列的插入操作称为入队
- 队列的删除操作称为出队
以下是队列中进行入队和出队的演示操作,数据1先进,也是数据1先出
代码实现
- 初始化队列
typedef struct queue{
int* elements; // 存储区
int cap; // 队列的容量
int rear; // 入队口
int front; // 出队口
int size; // 队列当前大小
}queue_t;
- 初始化队列
void queue_init(queue_t* pqueue, int cap){
// 分配存储区空间
pqueue->elements = malloc(sizeof(int) * cap);
if(pqueue->elements == NULL){
printf("内存分配失败\n");
return;
}
// 赋值容量
pqueue->cap = cap;
// 此时因为没有收数据,出队口和入队口都是0,队列当前大小也是0
pqueue->rear = 0;
pqueue->front = 0;
pqueue->size = 0;
}
- 销毁队列
void queue_deinit(queue_t* pqueue){
free(pqueue->elements);
pqueue->elements = NULL;
pqueue->cap = 0;
pqueue->rear = 0;
pqueue->front = 0;
pqueue->size = 0;
}
- 判断队列是否已满
int queue_full(queue_t* pqueue){
// 当size==cap的时候,说明已满,反之则没满
return pqueue->size == pqueue->cap;
}
- 判断队列是否为空
int queue_empty(queue_t* pqueue){
// 当size==0的时候,说明为空,反之则不为空
return pqueue->size == 0;
}
以下是一组入队出队的操作
- 入队
void queue_push(queue_t* pqueue, int data){
// 参考上面的视频,当此时还存在入队操作时,说明队列还没满,
// 但是此时rear已经超过索引值了(也就是与cap值相等),需要将rear重置为0;
if(pqueue->rear == pqueue=>cap)
pqueue->rear = 0;
pqueue->elements[pqueue->rear++] = data;
pqueue->size++;
}
- 出队
int queue_pop(queue_t* pqueue){
// 与入队函数类似,当此时还存在出队操作时,说明队列不为空,
// 但是此时front已经超过索引值了(也就是与cap值相等),需要将front重置为0
if(pqueue->front == pqueue->cap)
pqueue->front = 0;
pqueue->size--;
return pqueue->elements[pqueue->front++];
}
实例代码
创建三个文件: queue.c
、queue.h
、main.c
,实现上面动图中的操作
queue.c
定义队列具体的函数
#include "queue.h"
// 初始化队列
void queue_init(queue_t* pqueue, int cap){
pqueue->elements = malloc(sizeof(int) * cap);
if(pqueue->elements == NULL){
printf("分配队列存储区失败!\n");
return;
}
pqueue->cap = cap;
pqueue->rear = 0;
pqueue->front = 0;
pqueue->size = 0;
}
// 销毁队列
void queue_deinit(queue_t* pqueue){
free(pqueue->elements);
pqueue->elements = NULL;
pqueue->cap = 0;
pqueue->rear = 0;
pqueue->front = 0;
pqueue->size = 0;
}
// 入队
void queue_push(queue_t* pqueue, int data){
if(pqueue->rear == pqueue->cap)
pqueue->rear = 0;
pqueue->elements[pqueue->rear++] = data;
pqueue->size++;
}
// 出队
int queue_pop(queue_t* pqueue){
if(pqueue->front == pqueue->cap)
pqueue->front = 0;
pqueue->size--;
return pqueue->elements[pqueue->front++];
}
//判断队列是否已满
int queue_full(queue_t* pqueue){
return pqueue->size == pqueue->cap;
}
// 判断队列是否为空
int queue_empty(queue_t* pqueue){
return pqueue->size == 0;
}
queue.h
声明队列的相关函数和定义队列
#ifndef __QUEUE_H
#define __QUEUE_H
#include <stdio.h>
#include <stdlib.h>
// 定义队列
typedef struct queue{
int* elements;
int cap;
int rear;
int front;
int size;
}queue_t;
extern void queue_init(queue_t* pqueue, int cap);
extern void queue_deinit(queue_t* pqueue);
extern void queue_push(queue_t* pqueue, int data);
extern int queue_pop(queue_t* pqueue);
extern int queue_full(queue_t* pqueue);
extern int queue_empty(queue_t* pqueue);
#endif
main.c
主函数使用队列
#include "queue.h"
int main(void){
// 1. 创建一个队列
queue_t queue;
// 2. 初始化队列
queue_init(&queue, 4);
// 3. 入队4个数据
printf("开始第一次入队(4个数据): ");
int data = 10;
for(int i = 0; i < 4; i++){
if(!queue_full(&queue)){
printf("%d ", data);
queue_push(&queue, data);
data += 10;
}
}
printf("\n此时还剩%d个数据\n\n", queue.size);
// 4. 出队2个数据
printf("开始第一次出队(2个数据): ");
for(int i = 0; i < 2; i++){
if(!queue_empty(&queue)){
data = queue_pop(&queue);
printf("%d ", data);
}
}
printf("\n此时还剩%d个数据\n\n", queue.size);
// 5. 入队2个数据
printf("开始第二次入队(2个数据): ");
data = 10;
for(int i = 0; i < 2; i++){
if(!queue_full(&queue)){
printf("%d ", data);
queue_push(&queue, data);
data += 10;
}
}
printf("\n此时还剩%d个数据\n\n", queue.size);
// 6. 将所有数据全部取出
printf("将全部数据取出: ");
while(!queue_empty(&queue)){
data = queue_pop(&queue);
printf("%d ", data);
}
printf("\n此时还剩%d个数据\n\n", queue.size);
// 销毁队列
queue_deinit(&queue);
return 0;
}