问题描述:
请你仅用两个队列实现一个后入先出(LIFO)的栈,并支持普通队列的全部四种操作(push、top、pop和empty)。
实现MyStack类:
- void push(int x) 将元素x压入栈顶。
- int pop()移除并返回栈顶元素。
- int top()返回栈顶元素。
- boolean empty()如果栈是空的,返回true;否则,返回false。
解题思路:
1. 入数据,往不为空的队列入
2. 出数据,把不为空的队列数据导入为空,直至只剩最后一个
解决本题之前,要先将队列的各类接口函数准备好,队列的接口函数我上一篇中提到了喔:
#include<stdio.h>
#include<stdbool.h>
#include<assert.h>
#include<stdlib.h>
typedef int QDataType;
typedef struct QueueNode
{
struct QueueNode* next;
QDataType data;
}QNode;
//删除数据和插入数据需要记录头结点和尾结点
typedef struct Queue
{
QNode* head;
QNode* tail;
}Queue;
void QueueInit(Queue* pq);
void QueueDestory(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);
void QueueInit(Queue* pq)
{
assert(pq);
pq->head = pq->tail = NULL;
}
void QueueDestory(Queue* pq)
{
assert(pq);
QNode* cur = pq->head;
while (cur)
{
QNode* next = cur->next;
free(cur);
cur = next;
}
pq->head = pq->tail = NULL;//返回初始状态
}
//队尾入
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
printf("malloc fail\n");
exit(-1);
}
newnode->data = x;
newnode->next = NULL;
if (pq->tail == NULL)
{
pq->head = pq->tail = newnode;
}
else
{
pq->tail->next = newnode;
pq->tail = newnode;
}
}
//队头出
void QueuePop(Queue* pq)
{
assert(pq);
assert(pq->head);//断言队列是否为空,为空就不可删除,会有野指针
if (pq->head->next == NULL)//当只有一个节点时,tail可能为野指针,tail指向已释放的空间
pq->tail = NULL;
QNode* next = pq->head->next;
free(pq->head);
pq->head = next;
}
//取队头的数据
QDataType QueueFront(Queue* pq)
{
assert(pq);
assert(pq->head);
return pq->head->data;
}
//取队尾的数据
QDataType QueueBack(Queue* pq)
{
assert(pq);
assert(pq->head);
return pq->tail->data;
}
//取数据的个数
int QueueSize(Queue* pq)
{
assert(pq);
int size = 0;
QNode* cur = pq->head;
while (cur)
{
size++;
cur = cur->next;
}
return size;
}
//判断队列是否为空
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->head == NULL;
}
通过队列创建栈:
typedef struct
{
Queue q1;
Queue q2;
}MyStack;
MyStack* myStackCreate()
{
MyStack* ps = (MyStack*)malloc(sizeof(MyStack));
if (ps == NULL)
{
printf("malloc fail\n");
exit(-1);
}
QueueInit(&ps->q1);//对队列进行初始化
QueueInit(&ps->q2);
return ps;
}
在栈顶添加数据:
添加数据时,要在不为空的队列里添加:
void myStackPush(MyStack* obj, int x)
{
if (!QueueEmpty(&obj->q1))
{
QueuePush(&obj->q1,x);
}
else
{
QueuePush(&obj->q2, x);
}
}
从栈顶处删除数据并返回第一个数据:
int myStackPop(MyStack* obj)
{
Queue* emptyQ = &obj->q1;
Queue* nonemptyQ = &obj->q2;
if (!QueueEmpty(&obj->q1))
{
emptyQ=&obj->q2;
nonemptyQ=&obj->q1;
}
//倒数据
while (QueueSize(nonemptyQ) > 1)
{
//将不空的队列的头拷贝至空队列中
QueuePush(emptyQ, QueueFront(nonemptyQ));
QueuePop(nonemptyQ);//删除头数据
}
int top = QueueFront(nonemptyQ);
QueuePop(nonemptyQ);//删除最后一个数据,实现了后进先出
return top;
}
取栈顶的数据:
取不为空的队列的队尾数据:
int myStackTop(MyStack* obj)
{
if (!QueueEmpty(&obj->q1))
{
return QueueBack(&obj->q1);
}
else
{
return QueueBack(&obj->q2);
}
}
判断栈是否为空:
bool myStackEmpty(MyStack* obj)
{
return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
}
释放栈:
先销毁队列,再释放。
void myStackFree(MyStack* obj)
{
QueueDestory(&obj->q1);
QueueDestory(&obj->q2);
free(obj);
}
整体代码:
#include<stdio.h>
#include<stdbool.h>
#include<assert.h>
#include<stdlib.h>
typedef int QDataType;
typedef struct QueueNode
{
struct QueueNode* next;
QDataType data;
}QNode;
//删除数据和插入数据需要记录头结点和尾结点
typedef struct Queue
{
QNode* head;
QNode* tail;
}Queue;
void QueueInit(Queue* pq);
void QueueDestory(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);
void QueueInit(Queue* pq)
{
assert(pq);
pq->head = pq->tail = NULL;
}
void QueueDestory(Queue* pq)
{
assert(pq);
QNode* cur = pq->head;
while (cur)
{
QNode* next = cur->next;
free(cur);
cur = next;
}
pq->head = pq->tail = NULL;//返回初始状态
}
//队尾入
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
printf("malloc fail\n");
exit(-1);
}
newnode->data = x;
newnode->next = NULL;
if (pq->tail == NULL)
{
pq->head = pq->tail = newnode;
}
else
{
pq->tail->next = newnode;
pq->tail = newnode;
}
}
//队头出
void QueuePop(Queue* pq)
{
assert(pq);
assert(pq->head);//断言队列是否为空,为空就不可删除,会有野指针
if (pq->head->next == NULL)//当只有一个节点时,tail可能为野指针,tail指向已释放的空间
pq->tail = NULL;
QNode* next = pq->head->next;
free(pq->head);
pq->head = next;
}
//取队头的数据
QDataType QueueFront(Queue* pq)
{
assert(pq);
assert(pq->head);
return pq->head->data;
}
//取队尾的数据
QDataType QueueBack(Queue* pq)
{
assert(pq);
assert(pq->head);
return pq->tail->data;
}
//取数据的个数
int QueueSize(Queue* pq)
{
assert(pq);
int size = 0;
QNode* cur = pq->head;
while (cur)
{
size++;
cur = cur->next;
}
return size;
}
//判断队列是否为空
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->head == NULL;
}
typedef struct
{
Queue q1;
Queue q2;
}MyStack;
MyStack* myStackCreate()
{
MyStack* ps = (MyStack*)malloc(sizeof(MyStack));
if (ps == NULL)
{
printf("malloc fail\n");
exit(-1);
}
QueueInit(&ps->q1);
QueueInit(&ps->q2);
return ps;
}
void myStackPush(MyStack* obj, int x)
{
if (!QueueEmpty(&obj->q1))
{
QueuePush(&obj->q1,x);
}
else
{
QueuePush(&obj->q2, x);
}
}
//删除数据且返回栈顶
int myStackPop(MyStack* obj)
{
Queue* emptyQ = &obj->q1;
Queue* nonemptyQ = &obj->q2;
if (!QueueEmpty(&obj->q1))
{
emptyQ=&obj->q2;
nonemptyQ=&obj->q1;
}
//倒数据
while (QueueSize(nonemptyQ) > 1)
{
//将不空的队列的头拷贝至空队列中
QueuePush(emptyQ, QueueFront(nonemptyQ));
QueuePop(nonemptyQ);//删除头数据
}
int top = QueueFront(nonemptyQ);
QueuePop(nonemptyQ);//删除最后一个数据,实现了后进先出
return top;
}
int myStackTop(MyStack* obj)
{
if (!QueueEmpty(&obj->q1))
{
return QueueBack(&obj->q1);
}
else
{
return QueueBack(&obj->q2);
}
}
bool myStackEmpty(MyStack* obj)
{
return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
}
void myStackFree(MyStack* obj)
{
QueueDestory(&obj->q1);
QueueDestory(&obj->q2);
free(obj);
}