概述
队列特点
- 本质是操作受限的线性表,只能在一端进行插入操作,在另一端进行删除操作
- 先进先出(FIFO)
用途
- BFS(广度优先遍历)
- 找路问题
- 存放缓存信息
设计数据结构
typedef struct Queue {
TYPENAME *_pdata; //队列
int _size; //队列大小
int _front; //队头
int _back; //队尾, 指向最后一个元素的下一位置
}Queue_t, *pQueue_t;
循环队列的相关操作
-
初始化
-
容量(判空、判满、大小)
-
销毁(销毁堆空间)
-
访问(队头、队尾)
-
入队
-
出队
操作实现步骤
初始化(参数:队列地址,队列大小)
- 按照大小申请堆空间,并初始化
- front = rear = 0;
判空(参数:队列地址)
- return _front == _rear;
判满(参数:队列地址)
- return (rear + 1) % size == front
销毁(参数:队列地址)
- 如果堆空间存在,就释放
压栈(参数:队列地址,新元素)
-
如果队满,报错返回
-
如果队未满
- data[rear] = val;
- rear = (rear + 1) % size;
弹栈(参数:队列地址)
- 如果队空,报错返回
- 如果栈非空,front = (front + 1) % size
代码
头文件 SeqQueue.h
#ifndef __SEQQUEUE_H__
#define __SEQQUEUE_H__
#define TYPENAME int
typedef struct Queue {
TYPENAME *_pdata; //队列
int _size; //队列大小
int _front; //队头
int _back; //队尾
}Queue_t, *pQueue_t;
void queue_init(pQueue_t pQ, int size);
void queue_destroy(pQueue_t pQ);
int queue_empty(pQueue_t pQ);
int queue_full(pQueue_t pQ);
int queue_len(pQueue_t pQ);//返回队列长度
TYPENAME queue_front(pQueue_t pQ);//返回队头元素
TYPENAME queue_back(pQueue_t pQ);//返回队尾元素
int queue_push(pQueue_t pQ, TYPENAME val);
int queue_pop(pQueue_t pQ);
void queue_show(pQueue_t pQ);//显示队列元素
#endif
实现文件 SeqStack.c
#include "SeqQueue.h"
#include <stdio.h>
#include <stdlib.h>
void queue_show(pQueue_t pQ)
{
if (!queue_empty(pQ)) {
for (int i = pQ->_front; i != pQ->_back; i = (i + 1) % pQ->_size) {
printf("%d ", pQ->_pdata[i]);
}
printf("\n");
}
}
void queue_init(pQueue_t pQ, int size)
{
pQ->_pdata = (TYPENAME*)calloc(size, sizeof(TYPENAME));
pQ->_size = size;
pQ->_front = 0;
pQ->_back = 0;
}
void queue_destroy(pQueue_t pQ)
{
if (pQ->_pdata) {
free(pQ->_pdata);
pQ->_pdata = NULL;
pQ->_front = 0;
pQ->_back = 0;
}
}
int queue_empty(pQueue_t pQ)
{
return pQ->_front == pQ->_back;
}
int queue_full(pQueue_t pQ)
{
return (pQ->_back + 1) % pQ->_size == pQ->_front;
}
int queue_len(pQueue_t pQ)
{
int len = 0;
if (!queue_empty(pQ)) {
int start = pQ->_front;
for (; start != pQ->_back; start = (start + 1) % pQ->_size) {
++len;
}
}
return len;
}
TYPENAME queue_front(pQueue_t pQ)
{
if (!queue_empty(pQ)) {
return pQ->_pdata[pQ->_front];
}
else {
return EOF;
}
}
TYPENAME queue_back(pQueue_t pQ)
{
if (!queue_empty(pQ)) {
return pQ->_pdata[pQ->_back - 1];
}
else {
return EOF;
}
}
int queue_push(pQueue_t pQ, TYPENAME val)
{
if (!queue_full(pQ)) {
pQ->_pdata[pQ->_back] = val;
pQ->_back = (pQ->_back + 1) % pQ->_size;
return 0;
}
return -1;
}
int queue_pop(pQueue_t pQ)
{
if (!queue_empty(pQ)) {
pQ->_front = (pQ->_front + 1) % pQ->_size;
return 0;
}
return -1;
}
测试文件 test_seqstack.c
#include "SeqQueue.h"
#include <stdio.h>
void test0()
{
Queue_t que;
queue_init(&que, 8);
printf("\n----------test push------------\n");
for (int i = 3; i < 500; i *= 2) {
queue_push(&que, i);
}
printf("front: %d, back: %d, size: %d\n", queue_front(&que), queue_back(&que), queue_len(&que));
queue_show(&que);
printf("\n----------test pop------------\n");
queue_pop(&que);
queue_pop(&que);
queue_pop(&que);
queue_pop(&que);
printf("front: %d, back: %d, size: %d\n", queue_front(&que), queue_back(&que), queue_len(&que));
queue_show(&que);
printf("\n---------4push 2pop-----------\n");
queue_push(&que, 4);
queue_push(&que, 5);
queue_push(&que, 6);
queue_push(&que, 7);
queue_pop(&que);
queue_pop(&que);
printf("front: %d, back: %d, size: %d\n", queue_front(&que), queue_back(&que), queue_len(&que));
queue_show(&que);
}
int main()
{
test0();
}