“队列栈”:用一个队列实现一个栈
出栈思路:
1.将队列的队头元素取出,保存在变量data中,然后Pop掉,再将data Push进队列
2.若队列有n个元素,则需要进行步骤1 n -1 次后,此时队头元素就为此队列最后进入的值
1.Queue.h
#pragma once
#include <assert.h>
#include <String.h>
#include <stdlib.h>
// 利用单链表实现队列
typedef int QDataType;
// 队列结点定义
typedef struct QNode {
QDataType data; // 结点数据
struct QNode *pNext; //下一结点地址
} QNode;
// 队列链表的定义
typedef struct Queue {
QNode *pFront; //队头 :进行删除
QNode *pRear; //队尾 :进行插入
int size; //结点个数,即队列大小
} Queue;
// 队列初始化
void QueueInit(Queue *pQ)
{
assert(pQ != NULL);
pQ->pFront = pQ->pRear = NULL;
pQ->size = 0;
}
// 入队 : 从队尾插入一个元素
void QueuePush(Queue *pQ, QDataType data)
{
assert(pQ != NULL);
pQ->size++;
QNode *pNewNode = (QNode *)malloc(sizeof(QNode));
assert(pNewNode);
pNewNode->data = data;
pNewNode->pNext = NULL;
// 若队列为空
if (pQ->pRear == NULL) {
pQ->pFront = pQ->pRear = pNewNode;
return;
}
// 通常情况,即队列不为空,至少有一个结点
pQ->pRear->pNext = pNewNode;
pQ->pRear = pNewNode;
}
// 出队 :从队头删除一个元素
void QueuePop(Queue *pQ)
{
assert(pQ != NULL);
assert(pQ->size > 0); // 必须判断队列是否为空
pQ->size--;
// 通常情况
QNode *pNode = pQ->pFront;
pQ->pFront = pNode->pNext;
free(pNode);
// 若队列里面只有一个结点,删除后,队列为空,此时要改变队尾结点的状态
if (pQ->pFront == NULL) {
pQ->pRear = NULL;
}
}
// 返回队首元素
QDataType QueueFront(Queue *pQ)
{
assert(pQ != NULL);
assert(pQ->size > 0);
return pQ->pFront->data;
}
// 判断队列是否为空
// 1 为空, 0 不空
int QueueIsEmpty(Queue *pQ)
{
return pQ->size == 0 ? 1 : 0;
}
// 返回队列数据个数
int QueueSize(Queue *pQ)
{
return pQ->size;
}
void TestQueue()
{
Queue queue;
QueueInit(&queue);
QueuePush(&queue, 1);
QueuePush(&queue, 2);
QueuePush(&queue, 3);
QueuePush(&queue, 4);
QueuePop(&queue);
QueuePop(&queue);
QueuePop(&queue);
QueuePop(&queue);
}
2.QStack.h
#pragma once
#include "Queue.h"
#include <stdio.h>
/*
“队列栈”:用一个队列实现一个栈
出栈思路:
1.将队列的队头元素取出,保存在变量data中,然后Pop掉,再将data Push进队列
2.若队列有n个元素,则需要进行步骤1 n -1 次后,此时队头元素就为此队列最后进入的值
*/
typedef struct QStack {
Queue queue;
} QStack;
// 初始化
void QStackInit(QStack *pQS)
{
QueueInit(&(pQS->queue));
}
// 入栈
void QStackPush(QStack *pQS, QDataType data)
{
QueuePush(&(pQS->queue), data);
}
// 出栈
void QStackPop(QStack *pQS)
{
QDataType data;
Queue *pQ = &(pQS->queue);
for (int i = 1; i < QueueSize(pQ); i++) { //关键在于 i = 1,从1开始,若有n个元素,则循环 n - 1 次
data = QueueFront(pQ);
QueuePop(pQ);
QueuePush(pQ, data);
}
QueuePop(pQ);
}
// 返回栈顶元素
QDataType QStackTop(QStack *pQS)
{
QDataType data;
Queue *pQ = &(pQS->queue);
for (int i = 1; i < QueueSize(pQ); i++) { //关键在于 i = 1,从1开始,若有n个元素,则循环 n - 1 次
data = QueueFront(pQ);
QueuePop(pQ);
QueuePush(pQ, data);
}
// 关键点:取完栈顶数据后,必须恢复到入栈时顺序
data = QueueFront(pQ);
QueuePop(pQ);
QueuePush(pQ, data);
return data;
}
void TestQStack()
{
QStack qStack;
QStackInit(&qStack);
QStackPush(&qStack, 9);
QStackPush(&qStack, 5);
QStackPush(&qStack, 2);
QStackPush(&qStack, 7);
printf("%d\n",QStackTop(&qStack));
QStackPop(&qStack);
printf("%d\n", QStackTop(&qStack));
system("pause");
}
3.Main.c
//#include "Queue.h"
#include "QStack.h"
int main()
{
//TestQueue();
TestQStack();
return 0;
}