// 队列---------------------------------------------------------------------------------
// 只允许一端插入数据,另一端删除数据的特殊线性表
// 先进先出规则,FIFO
// 入队列:进行插入操作的称为队尾
// 出队列:进行删除操作的称为队头
//
// 数组队列:出栈需要遍历挪动数据,不推荐
// 链式队列:
//
typedef int QDatetype;
//创建一个结点
typedef struct QuequeNode
{
struct QuequeNode* next;
QDatetype val;
}QuequeNode;
//定义有头结点,有尾结点的结构体
typedef struct Queque
{
QuequeNode* head;
QuequeNode* tail;
}Queque;
//初始化
void QuequeInit(Queque* pq)
{
assert(pq);
pq->head = NULL;
pq->tail = NULL;
}
//销毁
void QuequeDestroy(Queque* pq)
{
assert(pq);
//从队头开始销毁,直到队尾遇到NULL
QuequeNode* cur = pq->head;
while (cur)
{
//记录下一个结点的位置
QuequeNode* next = cur->next;
//销毁当前结点
free(cur);
//cur往后迭代遍历
cur = next;
}
//队头队尾置空
pq->head = pq->tail = NULL;
}
//队尾入队列-插入
void QuequePush(Queque* pq, QDatetype x)
{
assert(pq);
//创建一个新结点,将x数据存入
QuequeNode* newNode = (QuequeNode*)malloc(sizeof(QuequeNode));
newNode->val = x;
newNode->next = NULL;
//队列内数据结点为空时,将队头队尾指向newNode
if (pq->head == NULL)
{
pq->head = pq->tail = newNode;
}
else
{
//将队尾的结点链接上newNode
pq->tail->next = newNode;
//将队尾指向newNode
pq->tail = newNode;
}
}
//队头出队列-删除
void QuequePop(Queque* pq)
{
assert(pq);
//断言QuequeEmpty(队列是否为空)的真假,非真则报错,非假继续
assert(!QuequeEmpty(pq));
//记录队头结点的下一个结点
QuequeNode* next = pq->head->next;
//释放队头结点空间
free(pq->head);
//头结点指向next
pq->head = next;
//遇到队尾,释放队尾结点,并将队尾置空,避免tail称为野指针
if (!next)//pq->head == NULL
{
pq->tail = NULL;
}
}
//取队头数据
QDatetype QuequeFront(Queque* pq)
{
assert(pq);
//断言QuequeEmpty(队列是否为空)的真假,非真则报错,非假继续
assert(!QuequeEmpty(pq));
return pq->head->val;
}
//取队尾数据
QDatetype QuequeBack(Queque* pq)
{
assert(pq);
//断言QuequeEmpty(队列是否为空)的真假,非真则报错,非假继续
assert(!QuequeEmpty);
return pq->tail->val;
}
//队列长度
size_t QuequeSize(Queque* pq)
{
assert(pq);
size_t count = 0;//计数
//从队头开始计数,遇到NULL结束
QuequeNode* cur = pq->head;
while (cur)
{
++count;
//cur往后迭代
cur = cur->next;
}
//返回计数
return count;
}
//判断是否为空
bool QuequeEmpty(Queque* pq)
{
assert(pq);
//不为空返回假(即返回判断不成立),为空返回真(队列为空)
return pq->head == NULL;
}
//两个队列实现栈----------------
//创建两个队列
typedef struct
{
Queque q1;
Queque q2;
}Mystack;
//开辟一个栈,包含两个队列,调用队列函数接口
Mystack* MystackCreate()
{
Mystack* st = (Mystack*)malloc(sizeof(Mystack));
//调用队列初始化函数
QuequeInit(&st->q1);
QuequeInit(&st->q2);
return st;
}
//压栈操作
void MystackPush(Mystack* obj, int x)
{
//如果q1不为空,调用入队列函数
if (!QuequeEmpty(&obj->q1))
{
QuequePush(&obj->q1, x);
}
else//否则入队列q2
{
QuequePush(&obj->q2, x);
}
}
//出栈操作
int MystackPop(Mystack* obj, int x)
{
//先找出空队列
//假设q1为空,q2不为空
Queque* emptyQ = &obj->q1;
Queque* noneEmptyQ = &obj->q2;
//纠错,如果q1不为空,则q2为空
if (!QuequeEmpty(&obj->q1))
{
Queque* emptyQ = &obj->q2;
Queque* noneEmptyQ = &obj->q1;
}
while(QuequeSize(noneEmptyQ)>1)//出队列直到留下最后一个数据
{
//取队头数据操作入空队列
QuequePush(emptyQ, QuequeFront(noneEmptyQ));
//队头出列
QuequePop(noneEmptyQ);
}
//取出最后一个数据
int top = QuequeFront(noneEmptyQ);
//出列,非空队列为空
QuequePop(noneEmptyQ);
//返回top实现后进先出
}
//取栈顶数据
int MystackTop(Mystack* obj)
{
//如果q1不为空
if (!QuequeEmpty(&obj->q1))
{
return QuequeBack(&obj->q1);//返回q1的队尾
}
else
{
return QuequeBack(&obj->q2);//返回q2的队尾
}
}
//判断是否为空
bool MystackEmpty(Mystack* obj)
{
//两个队列都为空,则为空
return QuequeEmpty(&obj->q1) && QuequeEmpty(&obj->q2);
}
//销毁
void MystackFree(Mystack* obj)
{
//先销毁两个队列
QuequeDestroy(&obj->q1);
QuequeDestroy(&obj->q2);
//再销毁obj
free(obj);
}