题海拾贝:力扣 225.用队列实现栈
Hello大家好!很高兴我们又见面啦!给生活添点passion,开始今天的编程之路!
我的博客:<但凡.
我的专栏:《编程之路》、《数据结构与算法之美》、《题海拾贝》
欢迎点赞,关注!
1、题目
题目链接:225. 用队列实现栈 - 力扣(LeetCode)
2、题解
由于我使用C语言写的,所以说前一部分都是队列的操作,直接复制过来的,从后面开始是模拟栈的内容。 简单概括一下思路就是如果要入栈,我就往这两个队列里不为空的那一个队里入,如果要出栈我就把不为空队里的元素出size个都出队列存放到另一个队里,只剩下一个元素,剩下的那个元素就正常删除就行。
typedef struct queueNode
{
int x;
struct queueNode* next;
}QN;//队列的节点
typedef struct QueueData
{
QN* phead;
int size;
QN* ptail;
}Q;//记录队列头尾
void InitQueue(Q* ph)
{
assert(ph);
ph->phead = ph->ptail = NULL;
ph->size = 0;
}
void QueueDestory(Q* ph)
{
assert(ph);
QN* cur = ph->phead;
while (cur)
{
QN* next = cur->next;
free(cur);
cur = next;
}
//队头队尾置空,否则队头队尾是野指针。
//队头队尾置空确保这个队列无法被使用(消失)
ph->phead = ph->ptail = NULL;
}
QN* buynode(int a)
{
QN* newnode = (QN*)malloc(sizeof(QN));
if (newnode == NULL)
{
perror("malloc fail!");
exit(1);
}
newnode->x = a;
newnode->next = NULL;
return newnode;
}
void Qpush(Q* ph,int x)
{
assert(ph);//保证队列存在
QN* newnode = buynode(x);
//队列 先进先出
//尾插
//注意处理两种情况
if (ph->phead==NULL)//此时队列没有节点
{
ph->phead = ph->ptail = newnode;
}
else
{
ph->ptail->next = newnode;
ph->ptail = newnode;
}
ph->size++;
}
bool QueueEmpty(Q* ph)
{
if (ph->size == 0)
{
return true;
}
else
{
return false;
}
}
//头删
//注意处理两种情况
void Qpop(Q* ph)
{
assert(!QueueEmpty(ph));//保证队列不为空
if (ph->phead == ph->ptail)//此时队列只有一个节点
{
free(ph->phead);
ph->ptail=ph->phead = NULL;
}
else
{
QN* next = (ph->phead)->next;
free(ph->phead);
ph->phead = next;
}
//关于置空的理解:如果释放一个指针后,让这个指针变量指向了下一个节点,也就是说没有变量找到那个刚刚释放的地址,就不会造成野指针的情况,也不用置空
//配合上面队列销毁理解。咱们只有把队头和队尾都置空,才能保证不会引用一个野指针,因为你队头和头尾这两个变量没有指向别的地方
ph->size--;
}
int QueueFront(Q* ph)
{
assert(!QueueEmpty(ph));//要保证队列里存在队头元素
return ph->phead->x;
}
int QueueBack(Q* ph)
{
assert(!QueueEmpty(ph));
return ph->ptail->x;
}
int Qsize(Q* ph)
{
assert(ph);
return ph->size;
}
//以上为C语言模拟队列
typedef struct {
Q queue1;
Q queue2;
} MyStack;
//初始化
MyStack* myStackCreate() {
MyStack* MST=(MyStack*)malloc(sizeof(MyStack));
InitQueue(&MST->queue1);
InitQueue(&MST->queue2);
return MST;
}
void myStackPush(MyStack* obj, int x) {
//往不为空的队列里插入
if(!QueueEmpty(&obj->queue1))
{
Qpush(&obj->queue1,x);
}
else{
Qpush(&obj->queue2,x);
}
}
int myStackPop(MyStack* obj) {
Q* p=&obj->queue1;//不空
Q* nonp=&obj->queue2;//空
if(!QueueEmpty(&obj->queue2))
{
p=&obj->queue2;
nonp=&obj->queue1;
}
//确定长短队列
while(Qsize(p)>1)
{
Qpush(nonp,QueueFront(p));
Qpop(p);
}
int top=QueueFront(p);
Qpop(p);
return top;
}
int myStackTop(MyStack* obj) {
Q* p=&obj->queue1;
Q* nonp=&obj->queue2;
if(!QueueEmpty(&obj->queue2))
{
p=&obj->queue2;
nonp=&obj->queue1;
}
//确定长短队列
while(Qsize(p)>1)
{
Qpush(nonp,QueueFront(p));
Qpop(p);
}
int top=QueueFront(p);
return top;
}
bool myStackEmpty(MyStack* obj) {
return QueueEmpty(&obj->queue1)&&QueueEmpty(&obj->queue2);
}
void myStackFree(MyStack* obj) {
QueueDestory(&obj->queue1);
QueueDestory(&obj->queue2);
free(obj);
obj=NULL;
}
好了,今天的内容就分享到这,我们下期再见!