个人主页: :✨✨✨初阶牛✨✨✨
强烈推荐优质专栏: C++的世界(持续更新中)
推荐专栏1: C语言初阶
推荐专栏2: C语言进阶
个人信条: 知行合一
在做这个题目之前,应当熟悉栈和队列这两种数据结构.栈和队列都是常见的数据结构,它们是基于数组或链表实现的线性数据结构。
栈(Stack):
栈是一种后进先出(Last-In-First-Out,LIFO)的数据结构,只允许在栈顶进行插入和删除操作。栈的基本操作包括入栈(push)、出栈(pop)、查看栈顶元素(top)和判断栈是否为空(empty)。
应用场景:实现程序调用的函数堆栈、表达式求值、括号匹配检验等。
队列(Queue):
队列是一种先进先出(First-In-First-Out,FIFO)的数据结构,只允许在队尾插入元素,在队头删除元素。队列的基本操作包括入队(enqueue)、出队(dequeue)、查看队头元素(front)和判断队列是否为空(empty)。
题目来源于–力扣
题目链接:传送门
请你仅使用两个队列实现一个后入先出(LIFO
)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。
实现 MyStack
类:
void push(int x)
将元素 x 压入栈顶。int pop()
移除并返回栈顶元素。int top()
返回栈顶元素。boolean empty()
如果栈是空的,返回 true
;否则,返回 false
。将模拟栈的结构定义为两个队列
typedef struct {
Queue q1;
Queue q2;
} MyStack;
调用两个栈对应的初始化函数.
代码实现:
MyStack* myStackCreate() {
MyStack* stack=( MyStack*)malloc(sizeof(MyStack));//开辟栈所占的空间(两个队列)
//初始化栈
QueueInit(&stack->q1);
QueueInit(&stack->q2);
return stack;
}
对于入栈操作,谁是空队列,就往这个队列中正常压数据,模拟压栈的过程.
代码实现:
void myStackPush(MyStack* obj, int x) {
if(!QueueEmpty(&obj->q1))//如果其中一个队列是空,就往空的队列中插入元素
{
QueuePush(&obj->q1,x);
}
else{
QueuePush(&obj->q2,x);
}
}
出队列相对麻烦一些:
代码实现:
int myStackPop(MyStack* obj) {
Queue* empty=&obj->q1;//假设q1是空队列
Queue* Notempty=&obj->q2;
if(!QueueEmpty(&obj->q1))//如果假设错误,则说明q2才是空队列
{
empty=&obj->q2;
Notempty=&obj->q1;
}
//将除了最后一个要删除的元素以外其他元素,倒数据到空队列
while(QueueSize(Notempty)>1)
{
//将有元素的队列中的队头的值放入空队列中
QueuePush(empty,QueueFront(Notempty));
//弹出这个队头元素
QueuePop(Notempty);
}
int top=QueueFront(Notempty);
QueuePop(Notempty);//删除剩下的最后一个元素.
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;
//return QueueEmpty(&obj->q1)&&QueueEmpty(&obj->q2);
}
代码实现:
void myStackFree(MyStack* obj) {
//先释放栈中申请的链式队列
QueueDestroy(&obj->q1);
QueueDestroy(&obj->q2);
//最后释放栈这个结构体
free(obj);
}
//手撕队列
/*
...
*/
typedef struct {
Queue q1;
Queue q2;
} MyStack;
MyStack* myStackCreate() {
MyStack* stack=( MyStack*)malloc(sizeof(MyStack));//开辟栈所占的空间(两个队列)
//初始化栈
QueueInit(&stack->q1);
QueueInit(&stack->q2);
return stack;
}
void myStackPush(MyStack* obj, int x) {
if(!QueueEmpty(&obj->q1))//如果其中一个队列是空,就往空的队列中插入元素
{
QueuePush(&obj->q1,x);
}
else{
QueuePush(&obj->q2,x);
}
}
int myStackPop(MyStack* obj) {
Queue* empty=&obj->q1;//假设q1是空队列
Queue* Notempty=&obj->q2;
if(!QueueEmpty(&obj->q1))//如果假设错误,则说明q2才是空队列
{
empty=&obj->q2;
Notempty=&obj->q1;
}
//将除了最后一个要删除的元素以外其他元素,倒数据到空队列
while(QueueSize(Notempty)>1)
{
//将有元素的队列中的队头的值放入空队列中
QueuePush(empty,QueueFront(Notempty));
//弹出这个队头元素
QueuePop(Notempty);
}
int top=QueueFront(Notempty);
QueuePop(Notempty);//删除剩下的最后一个元素.
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;
//return QueueEmpty(&obj->q1)&&QueueEmpty(&obj->q2);
}
void myStackFree(MyStack* obj) {
//先释放栈中申请的链式队列
QueueDestroy(&obj->q1);
QueueDestroy(&obj->q2);
//最后释放栈这个结构体
free(obj);
}
/**
* Your MyStack struct will be instantiated and called as such:
* MyStack* obj = myStackCreate();
* myStackPush(obj, x);
* int param_2 = myStackPop(obj);
* int param_3 = myStackTop(obj);
* bool param_4 = myStackEmpty(obj);
* myStackFree(obj);
*/
//手撕队列
typedef int QDatatype;
typedef struct QueueNode
{
struct QueueNode* next;
QDatatype data;
}QNode;
typedef struct Queue
{
QNode* head;
QNode* tail;
int size;
}Queue;
void QueueInit(Queue* pq);
void QueueDestroy(Queue* pq);
void QueuePush(Queue* pq, QDatatype x);
void QueuePop(Queue* pq);
int QueueSize(Queue* pq);
bool QueueEmpty(Queue* pq);
QDatatype QueueFront(Queue* pq);
QDatatype QueueBack(Queue* pq);
void QueueInit(Queue* pq)//队列的初始化
{
assert(pq);
pq->head = pq->tail = NULL;
pq->size = 0;
}
void QueueDestroy(Queue* pq)//销毁队列操作
{
assert(pq);
QNode* cur = pq->head;
QNode* next = cur;
while (next)
{
next = cur->next;
free(cur);
cur = next;
}
pq->head = pq->tail = NULL;
pq->size = 0;
}
void QueuePush(Queue* pq, QDatatype x)//入队列操作
{
assert(pq);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
newnode->data = x;
newnode->next = NULL;
if (newnode == NULL)
{
perror("newnode malloc fail:");
return;
}
if (pq->head == NULL)//第一次插入
{
assert(pq->tail==NULL);
pq->head = pq->tail = newnode;
}
else
{
pq->tail->next = newnode;
pq->tail = newnode;
}
pq->size++;
}
bool QueueEmpty(Queue* pq)//队列的判空操作
{
assert(pq);
if (pq->head == pq->tail && pq->head == NULL)
{
return true;
}
return false;
}
void QueuePop(Queue* pq)//出队列
{
assert(pq);
assert(!QueueEmpty(pq));
if (pq->head->next == NULL)//代表还剩下一个结点
{
free(pq->head);//释放这个结点.
pq->head = pq->tail = NULL;
}
else
{
QNode* next = pq->head->next;
free(pq->head);
pq->head = next;
}
pq->size--;
}
int QueueSize(Queue* pq)//队列元素的大小
{
assert(pq);
return pq->size;
}
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;
}