题目要求:
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push
、top
、pop
和 empty
)。
实现 MyStack 类:
void push(int x) 将元素 x 压入栈顶。
int pop() 移除并返回栈顶元素。
int top() 返回栈顶元素。
boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。
思路:
由于栈的原则为后进先出,而队列的进出原则为先进先出
当两个队列都为空时,可将元素存入任意一个队列中
当有一个队列存入元素,此后所有的元素都存入这个队列中
为了实现栈顶数据的删除,将队列1中的非末尾数据依次保存在队列2中,使得队列1中只剩最后需要删除的元素,即栈顶元素
同理,如果想删除数字4,则将123保存至队列1,后将队列2中的4删除
插入数据则将数据插入至有数据存放的队列
代码实现:
//请你仅使用两个队列实现一个后入先出(LIFO)的栈
//并支持普通栈的全部四种操作(push、top、pop 和 empty)
#include<stdio.h>
#include<assert.h>
#include<stdbool.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* Q1);
void QueueDestory(Queue* Q1);
void QueuePush(Queue* Q1, QDataType x);//队尾入
void QueuePop(Queue* Q1);//队头出
QDataType QueueFront(Queue* Q1);
QDataType QueueBack(Queue* Q1);
int QueueSize(Queue* Q1);
bool QueueEmpty(Queue* Q1);
void QueueInit(Queue* Q1)
{
assert(Q1);
Q1->head = Q1->tail = NULL;
}
void QueueDestory(Queue* Q1)
{
assert(Q1);
QNode* cur = Q1->head;
while (cur)
{
QNode* next = cur->next;
free(cur);
cur = next;
}
}
void QueuePush(Queue* Q1, QDataType x)
{
assert(Q1);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
printf("malloc fail\n");
exit(-1);
}
newnode->data = x;
newnode->next = NULL;
if (Q1->tail == NULL)
{
Q1->head = Q1->tail = newnode;
}
else
{
Q1->tail->next = newnode;//在tail后插入新结点
Q1->tail = newnode;//将新结点变为为结点
}
}
void QueuePop(Queue* Q1)
{
assert(Q1);
assert(Q1->head);//保证队列存在,并且队列不为空
if (Q1->head->next == NULL)
{
free(Q1->head);
Q1->head = Q1->tail = NULL;//将队头队尾指针置空,避免野指针问题
}
else
{
QNode* next = Q1->head->next;
free(Q1->head);
Q1->head = next;
}
}
QDataType QueueFront(Queue* Q1)
{
assert(Q1);
assert(Q1->head);
return Q1->head->data;
}
QDataType QueueBack(Queue* Q1)
{
assert(Q1);
assert(Q1->tail);
return Q1->tail->data;
}
int QueueSize(Queue* Q1)
{
assert(Q1);
int size = 0;
QNode* cur = Q1->head;
while (cur)
{
++size;
cur = cur->next;
}
return size;
}
bool QueueEmpty(Queue* Q1)
{
assert(Q1);
return Q1->head == NULL;
}
typedef struct Stack//栈
{
Queue Q1;
Queue Q2;
}MyStack;
MyStack* myStackCreate() //初始化
{
//如下这种方法不可以实现,在函数中创建的变量作为返回值,返回值为局部变量
//MyStack st;
//return &st;
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)
{
//下面这种方法不可以使用,编译会报错
//原因是因为QueuePush在定义实现时,插入的数据类型为STDataType
//if (QueueEmpty(& obj->Q1))//如果Q1为空
//{
// if (QueueSize(&obj->Q2)>1)
// {
// QueuePush(&obj->Q1, QueueFront(&obj->Q2));//如果Q2存储数据超过1个,则将数据插入Q1中
// }
// else
// {
// QueuePop(&obj->Q2);//只剩一个数据时,将Q2中的数据删除
// }
//}
//else
//{
// if (QueueSize(&obj->Q1) > 1)
// {
// QueuePush(&obj->Q2, &obj->Q1);//如果Q2存储数据超过1个,则将数据插入Q1中
// }
// else
// {
// QueuePop(&obj->Q1);//只剩一个数据时,将Q2中的数据删除
// }
//}
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)
{
if (QueueEmpty(&obj->Q1)&&QueueEmpty(&obj->Q2))
{
return true;
}
else
{
return false;
}
}
void myStackFree(MyStack* obj)
{
QueueDestory(&obj->Q1);
QueueDestory(&obj->Q2);
free(obj);
}