LeetCode225OJ题---用队列实现栈

. - 力扣(LeetCode)

做该种题要记住两个关键点:
一个队列用来插入数据。一个队列用来存数据

1.空队列用来导数据
2.非空队列用来插入数据

我们知道队列的特点:先进先出,只能在一端插入,一端删除。
而栈的特点是:先进后出,后进先出。

比如要让两个队列实现栈的功能,就拿出栈来说,如果要应该将栈顶元素5拿走。
但在队列1中,因为只能在队头进行删除,所以只能拿走元素1.
那该怎么办呢?

要想pop掉队列中的元素5,我们得想办法将它搞成队头元素才行,这样才可以删除掉它。而如果队列2是空队列的话,那么我们这样做:将元素5之前的4个元素都放到队列2中,队列1中就只剩下元素5了,那元素5就相当于队头元素,就可以进行pop操作最终将其删除掉了,删除后队列1又变成空队列了。
而队列2就是非空队列。而重复这样的操作就可以实现删除栈顶元素的操作了:
首先将非空队列中前n-1个元素导入空队列中,然后再pop掉非空队列中的元素。

完整代码:

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){
    assert(pq);
    pq->phead=pq->ptail=NULL;
    pq->size=0;
}
//销毁队列
void QueueDestroy(Queue*pq){
    assert(pq);
    QNode *pcur=pq->phead;
    while(pcur){
        QNode*next=pcur->next;
        free(pcur);
        pcur=next;
    }
    pq->phead=pq->ptail=NULL;
    pq->size=0;
}
//队尾插入
void QueuePush(Queue*pq,QDataType x){
    assert(pq);
    QNode*newnode=(QNode*)malloc(sizeof(QNode));
    if(newnode==NULL){
        perror("malloc fail");
        return;
    }
    newnode->next=NULL;
    newnode->val=x;
    if(pq->ptail==NULL){
        pq->ptail=pq->phead=newnode;
    }
    else{
        pq->ptail->next=newnode;
        pq->ptail=newnode;
    }
    pq->size++;
}
//队头删除
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--;
}
//取队头队尾
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;
}
//取队长度
int QueueSize(Queue*pq){
    assert(pq);
    return pq->size;
}
bool QueueEmpty(Queue*pq){
    assert(pq);
    return pq->size==0;
}
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);
}
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) {
    QueueDestroy(&(obj->q1));
    QueueDestroy(&(obj->q2));
    free(obj);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值