顺序队列(循环队列)
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
队列又称为先进先出(FIFO—first in first out)线性表
下面画图描述了入队和出队。
当数据存入时队尾(rear)下标会增加。
数据取出时队首(front)下标会增加指向下一个待出队的元素。
在顺序队列中当队首或队尾大于规定的下标(cap)大小时,队首和队尾的下标会返回0的位置。
下面用代码实现编写些功能测试效果。
- 队列的初始化
- 清空队列
- 判断队列空或满
- 数据入队
- 数据出队
- 返回队首元素数据
- 元素的个数
将上边函数写入一个头文件进行声明,让编译器识别。
queue.h
#ifndef QUEUE_H_INCLUDE
#define QUEUE_H_INCLUDE
#include <sys/types.h>
/*队列的组成部分*/
typedef struct queue
{
int *arr;
size_t cap;
size_t front;
size_t rear;
size_t size;
}QUEUE;
/*队列初始化*/
void queue_init(QUEUE *queue,size_t cap);
/*清空队列*/
void queue_deinit(QUEUE *queue);
/*判空*/
int queue_empty(QUEUE *queue);
/*判满*/
int queue_full(QUEUE *queue);
/*入队*/
void queue_push(QUEUE *queue,int data);
/*出队*/
int queue_pop(QUEUE *queue);
/*队首元素*/
int queue_front(QUEUE *queue);
/*元素个数*/
size_t queue_size(QUEUE* queue);
#endif
下边编写个源文件将函数进行定义并调用实现
#include"queue.h"
#include<stdio.h>
#include<stdlib.h>
/*初始化队列*/
void queue_init(QUEUE *queue,size_t cap)
{
/*分配内存*/
queue->arr=malloc(cap* sizeof(int));
queue->front=0;
queue->rear=0;
queue->cap=cap;
queue->size=0;
}
/*清空释放队列*/
void queue_deinit(QUEUE *queue)
{
free(queue->arr);
queue->arr=NULL;
queue->cap=0;
queue->rear=0;
queue->front=0;
queue->size=0;
}
/*判空*/
int queue_empty(QUEUE *queue)
{
/*元素数量为0时则为空*/
return !queue->size;
}
/*判满*/
int queue_full(QUEUE *queue)
{
/*元素数量大于或等于规定容量大小时则为满*/
return queue->size>=queue->cap;
}
/*入队*/
void queue_push(QUEUE *queue,int data)
{
/*当队尾下标大于规定容量下标时,队尾下标重0开始*/
if(queue->rear >= queue->cap)
{
queue->rear=0;
}
queue->size += 1;
queue->arr[queue->rear++]=data;
}
/*出队*/
int queue_pop(QUEUE *queue)
{
/*当队首下标大于规定容量下标时,队首下标重0开始*/
if(queue->front >= queue->cap)
queue->front=0;
queue->size -= 1;
return queue->arr[queue->front++];
}
/*输出元素队首*/
int queue_front(QUEUE *queue)
{
/*当队首下标大于规定容量下标时,队首下标重0开始*/
if(queue->front >= queue->cap)
queue->front=0;
return queue->arr[queue->front];
}
/*元素数量*/
size_t queue_size(QUEUE* queue)
{
return queue->size;
}
/*mian函数调用*/
int main()
{
QUEUE queue_a;
queue_init(&queue_a,6);
printf("入队顺序为 1 2 3 4 5 \n");
printf("\n");
for (int i = 0; !queue_full(&queue_a); ++i)
{
queue_push(&queue_a,i+1);
}
printf("元素数量为:%d\n",queue_size(&queue_a));
printf("队首元素数据为%d\n",queue_front(&queue_a));
printf("出队:\n");
while(!queue_empty(&queue_a))
{
printf("队首为:%d\n",queue_front(&queue_a));
printf("数据:%d\n",queue_pop(&queue_a));
printf("\n");
}
queue_deinit(&queue_a);
return 0;
}
下面是编译运行的效果图
在循环队列中队首控制出队顺序,队尾控制入队顺序。下篇将复习链式存储结构的队列。88啦。