目录
1:思路分析
1):题目要求我们用两个队列实现栈的出栈、入栈、取栈顶数据等,所以我们可以这里用两个队列来相互导数据,因为队列是先进队列的数据就先出队列,所以我们这里并且保持一个队列存数据,一个队列为空,如下图:
2):入数据就如不为空的队列,导数据就将不为空的队列中的数据导到为空的队列当中去(将q2中的的数据导到q1当中去) ,如果还要入数据的的话就入到q1当中去
2:栈的实现
1):因为我们是用C语言实现,所以需要手搓一下栈,一下是栈的实现代码:
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <stdbool.h>
typedef int QDatatype;
typedef struct QueueNode
{
struct QueueNode* next;
QDatatype val;
}QNode;
typedef struct Queue
{
QNode* phead;
QNode* ptail;
int size;
}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->phead = NULL;
pq->ptail = NULL;
pq->size = 0;
}
//尾插
void QueuePush(Queue* pq, QDatatype x)
{
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
perror("malloc fail");
return;
}
newnode->next = NULL;
newnode->val = x;
if (pq->ptail == NULL)
{
pq->phead = pq->ptail = newnode;
}
else
{
pq->ptail->next = newnode;
pq->ptail = newnode;
}
pq->size++;
}
void QueueDestory(Queue* pq)
{
assert(pq);
QNode* cur = pq->phead;
while (cur)
{
QNode* next = cur->next;
free(cur);
cur = next;
}
pq->phead = pq->ptail = NULL;
pq->size = 0;
}
void QueuePop(Queue* pq)
{
assert(pq);
assert(pq->size != 0);
if (pq->phead->next == NULL)
{
free(pq->phead);
pq->phead = pq->ptail = NULL;
}
else
{
QNode* next = pq->phead->next;
free(pq->phead);
pq->phead = next;
}
pq->size--;
}
int QueueSize(Queue* pq)
{
assert(pq);
return pq->size;
}
QDatatype QueueFront(Queue* pq)
{
assert(pq);
assert(pq->phead);
return pq->phead->val;
}
QDatatype QueueBack(Queue* pq)
{
assert(pq);
assert(pq->ptail);
return pq->ptail->val;
}
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->size == 0;
}
3: 队列实现栈
1):定义队列
首先我们先定义两个队列,Queue q1 和 Queue q2
typedef struct {
Queue q1;
Queue q2;
} MyStack;
2):初始化队列
定义好队列后,我们需要对队列初始化,我们这里可以直接调用栈的初始化QueueInit,对Queue q1 和 Queue q2 进行初始化
MyStack* myStackCreate() {
MyStack* pst = (MyStack*)malloc(sizeof(MyStack));
QueueInit(&(pst->q1));
QueueInit(&(pst->q2));
return pst;
}
3):插入数据
接下来我们实现插入操作,在插入时,我们需要对队列q1进行判空,如果q1不为空,我们就将数据插入到q1中去,(else)q1为空的话,我们就将数据插入到q2中去,因为本题2我们是始终让一个队列不为空,一个队列为空的
void myStackPush(MyStack* obj, int x) {
if(!QueueEmpty(&obj->q1))
{
QueuePush(&obj->q1,x);
}
else
{
QueuePush(&obj->q2,x);
}
}
3):删除数据
删除操作这里我们可以用一下假设法:先假设q1为空(empty),假设q2为非空(nonEmpty),当q1为非空时,那么就说明我们假设错了,则q1为非空(nonEmpty),q2为空(empty)
然后对非空队列(nonEmpty)进行导数据,将非空队列(nonEmpty)的数据导到空队列(empty)当中去,直到队尾的数据时停止导数据(将不为空前szie-1导走,删除最后一个就是顶部数据),保存非空队列(nonEmpty)中的最后一个数,并将其删除(pop)掉,然后返回保存的最后一个数即可
int myStackPop(MyStack* obj) {
//假设法
Queue* empty = &(obj->q1);//空
Queue* nonEmpty = &(obj->q2);//非空
if(!QueueEmpty(&obj->q1))
{
nonEmpty = &(obj->q1);
empty = &(obj->q2);
}
//不为空前szie-1导走,删除最后一个就是顶部数据
while(QueueSize(nonEmpty) > 1)
{
QueuePush(empty,QueueFront(nonEmpty));
QueuePop(nonEmpty);
}
int top = QueueFront((nonEmpty));
QueuePop(nonEmpty);
return top;
}
4):取栈顶数据
取数据时我们先要判断一下q1和q2,如果是q1不为空,那么q2为空,我们直接返回q1的队尾数据
如果是q2不为空,那么q1为空,我们直接返回q2的队尾数据
int myStackTop(MyStack* obj) {
if(!QueueEmpty(&obj->q1))
{
return QueueBack(&(obj->q1));
}
else
{
return QueueBack(&(obj->q2));
}
}
5): 判空
分别队q1和q2进行判空,然后返回q1和q2
bool myStackEmpty(MyStack* obj) {
return QueueEmpty(&(obj->q1)) && QueueEmpty(&(obj->q2));
}
6):释放
在释放的时候我们不能直接释放栈(free(obj)),因为q1队列中还有szie个元素没有释放掉,如果直接free(obj),那么q1队列中的数就成了野指针,所以我们需要分别释放掉q1和q2,最后再整体释放掉obj
void myStackFree(MyStack* obj) {
QueueDestory(&(obj->q1));
QueueDestory(&(obj->q2));
free(obj);
}
4:总代码
typedef struct {
Queue q1;
Queue q2;
} MyStack;
MyStack* myStackCreate() {
MyStack* pst = (MyStack*)malloc(sizeof(MyStack));
QueueInit(&(pst->q1));
QueueInit(&(pst->q2));
return pst;
}
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);//空
Queue* nonEmpty = &(obj->q2);//非空
if(!QueueEmpty(&obj->q1))
{
nonEmpty = &(obj->q1);
empty = &(obj->q2);
}
//不为空前szie-1导走,删除最后一个就是顶部数据
while(QueueSize(nonEmpty) > 1)
{
QueuePush(empty,QueueFront(nonEmpty));
QueuePop(nonEmpty);
}
int top = QueueFront((nonEmpty));
QueuePop(nonEmpty);
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);
}
以上就是用队列实现栈问题的所有思路和分析了,创作不易,求求大家点个小赞赞,感谢各位老们的赏脸观看,随手点个赞,养成好习惯,如有问题,感谢反馈!