队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出
FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头
队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数
组头上出数据,效率会比较低。
与栈类似,可以把声明与定义分开
头文件.h
#include
#include
#include
#include
#include
typedef int QDataType;
typedef struct QueueNode
{
struct QueueNode* next;
QDataType val;
}QNode;
typedef struct Queue
{
QNode* phead;//头节点指针
QNode* ptail;//结尾节点指针
int size;
}Queue;
//接口
void QueueInit(Queue* pq);
void QueueDestroy(Queue* pq);
// 队尾插入
void QueuePush(Queue* pq, QDataType x);
// 队头删除
void QueuePop(Queue* pq);
// 取队头和队尾的数据
QDataType QueueFront(Queue* pq);
QDataType QueueBack(Queue* pq);
int QueueSize(Queue* pq);
bool QueueEmpty(Queue* pq);
实现文件.c(接口实现)
void QueueInit(Queue* pq)
{
pq->phead = NULL;
pq->ptail = NULL;
pq->size = 0;
}
void QueueDestroy(Queue* pq)
{
assert(pq);
assert(pq->phead);
if (pq->phead == pq->ptail)
{
free(pq->phead);
pq->phead = pq->ptail = NULL;
pq->size = 0;
}
}
// 队尾插入
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
QNode* new = (QNode*)malloc(sizeof(QNode));
if (new == NULL)
{
perror("malloc fail");
return;
}
new->next = NULL;
new->val = x;
if (pq->phead == NULL)//链表为空
{
pq->phead = pq->ptail = new;
pq->size++;
}
else//有多个节点
{
pq->ptail->next = new;
pq->ptail = new;
pq->size++;
}
}
// 队头删除
void QueuePop(Queue* pq)
{
assert(pq);
assert(pq->size != 0);
if (pq->phead->next == NULL)
{
free(pq->phead);
pq->phead = pq->ptail = NULL;
pq->size--;
}
else
{
Queue* cur = pq->phead->next;
free(pq->phead);
pq->phead = cur;
pq->size--;
}
}
// 取队头和队尾的数据
QDataType QueueFront(Queue* pq)
{
assert(pq);
assert(pq->size != 0);
return pq->phead->val;
}
QDataType QueueBack(Queue* pq)
{
assert(pq);
assert(pq->size != 0);
return pq->ptail->val;
}
int QueueSize(Queue* pq)
{
assert(pq);
return pq->size;
}
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->size == 0;
}
1、用队列实现栈链接: 用队列实现栈链接
首先实现一个队列,然后在构建俩个队列,俩个队列互相导数据
//队列
-----------------------------------------------
typedef struct {
Queue q1;
Queue q2;
} MyStack;
MyStack* myStackCreate() {
MyStack* p = (MyStack*)malloc(sizeof(MyStack));
QueueInit(&p->q1);
QueueInit(&p->q2);
return p;
}
void myStackPush(MyStack* obj, int x)
{
if (QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2))//俩个都为空
{
QueuePush(&(obj->q1), x);
}
else if (!QueueEmpty(&obj->q1))//向有数据的队列插入数据
{
QueuePush(&(obj->q1), x);
}
else
{
QueuePush(&(obj->q2), x);
}
}
int myStackPop(MyStack* obj)
{
Queue* empty = &obj->q1;
Queue* noempty = &obj->q2;
if (QueueEmpty(&obj->q2))
{
empty = &obj->q2;
noempty = &obj->q1;
}
while (QueueSize(noempty) > 1)
{
QueuePush(empty, QueueFront(noempty));
QueuePop(noempty);
}
int ret = QueueFront(noempty);
QueuePop(noempty);
return ret;
}
int myStackTop(MyStack* obj) {
if (QueueEmpty(&obj->q2))
{
return QueueBack(&obj->q1);
}
else
{
return QueueBack(&obj->q2);
}
}
bool myStackEmpty(MyStack* obj) {
return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
}
void myStackFree(MyStack* obj)
{
QueueDestroy(&(obj->q2));
QueueDestroy(&(obj->q1));
free(obj);
}