概述
队列特点
- 本质是操作受限的线性表,只能在一端进行插入操作,在另一端进行删除操作
- 先进先出(FIFO)
用途
- BFS(广度优先遍历)
- 找路问题
- 存放缓存信息
设计数据结构
//链队节点
typedef struct Node {
TYPENAME _data;
struct Node *_pNext;
}Node_t, *pNode_t;
//链队
typedef struct Queue {
pNode_t _front; //队头
pNode_t _back; //队尾
int _size; //队列大小
}Queue_t, *pQueue_t;
循环队列的相关操作
-
初始化
-
容量(判空、大小)
-
销毁(销毁堆空间)
-
访问(队头、队尾)
-
入队
-
出队
操作实现步骤
初始化(参数:队列地址,队列大小)
- 队列置空
判空(参数:队列地址)
- return NULL == front;
销毁(参数:队列地址)
- 队列有结点,挨个释放
压栈(参数:队列地址,新元素)
- 新建结点,初始化
- 如果队列为空,队头队尾指向新节点
- 如果队列非空,新节点尾插入链表,++size
弹栈(参数:队列地址)
- 如果队空,报错返回
- 如果队非空,保存队头,队头后移,释放原队头节点,–size
代码
头文件 LinkQueue.h
#ifndef __LINKQUEUE_H__
#define __LINKQUEUE_H__
#define TYPENAME int
//链队节点
typedef struct Node {
TYPENAME _data;
struct Node *_pNext;
}Node_t, *pNode_t;
//链队
typedef struct Queue {
pNode_t _front; //队头
pNode_t _back; //队尾
int _size; //队列长度
}Queue_t, *pQueue_t;
void queue_init(pQueue_t pQ);
void queue_destroy(pQueue_t pQ);
int queue_empty(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
实现文件 LinkStack.c
#include "LinkQueue.h"
#include <stdio.h>
#include <stdlib.h>
void queue_show(pQueue_t pQ)
{
if (!queue_empty(pQ)) {
pNode_t pCur = pQ->_front;
for (; pCur; pCur = pCur->_pNext) {
printf("%d ", pCur->_data);
}
printf("\n");
}
}
void queue_init(pQueue_t pQ)
{
pQ->_front = NULL;
pQ->_back = NULL;
pQ->_size = 0;
}
void queue_destroy(pQueue_t pQ)
{
if (pQ->_front) {
pNode_t pPre = pQ->_front;
pNode_t pCur = pPre->_pNext;
for (; pCur; pPre = pCur, pCur = pCur->_pNext) {
free(pPre);
pPre = NULL;
}
pQ->_front = NULL;
pQ->_back = NULL;
pQ->_size = 0;
}
}
int queue_empty(pQueue_t pQ)
{
return NULL == pQ->_front;
}
int queue_len(pQueue_t pQ)
{
return pQ->_size;
}
TYPENAME queue_front(pQueue_t pQ)
{
if (!queue_empty(pQ)) {
return pQ->_front->_data;
}
else {
return EOF;
}
}
TYPENAME queue_back(pQueue_t pQ)
{
if (!queue_empty(pQ)) {
return pQ->_back->_data;
}
else {
return EOF;
}
}
int queue_push(pQueue_t pQ, TYPENAME val)
{
pNode_t pNew = (pNode_t)calloc(1, sizeof(Node_t));
pNew->_data = val;
if (queue_empty(pQ)) {
//如果队列为空
pQ->_front = pQ->_back = pNew;
}
else {
//队列非空, 尾插
pQ->_back->_pNext = pNew;
pQ->_back = pNew;
}
++pQ->_size;
return 0;
}
int queue_pop(pQueue_t pQ)
{
if (!queue_empty(pQ)) {
pNode_t pCur = pQ->_front;
pQ->_front = pQ->_front->_pNext;
--pQ->_size;
//释放队头结点
free(pCur);
pCur = NULL;
return 0;
}
return -1;
}
测试文件 test_seqstack.c
#include "LinkQueue.h"
#include <stdio.h>
void test0()
{
Queue_t que;
queue_init(&que);
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();
}