剑指 Offer 09. 用两个栈实现队列

这篇博客介绍了一种使用两个栈实现队列数据结构的方法。在add栈中添加元素,当需要删除元素时,如果del栈为空,会将add栈所有元素转移到del栈。这种设计允许在O(1)的时间复杂度内完成入队和出队操作。博客还讨论了空间优化的可能性,但为了简化代码,选择了固定大小的栈。

在这里插入图片描述
思路:
一个add栈负责添加元素,一个del栈负责删除元素。
(1)加入元素:直接向add栈添加
(2)删除元素:需要判断del栈的状态。
若del栈空,且add栈空,则没有要删除的元素。
若del栈空,且add栈非空,则将add栈的元素出栈然后压入del栈,此时del栈栈顶元素就是队首元素。
除了前两种情况,则del栈非空,del栈栈顶元素直接出栈。

该图来leetcode官方题解
在这里插入图片描述

为了省事,给栈申请了题目限制的最大空间10000,有点浪费内存空间。
可以考虑使用栈空间动态扩容,但是会增加代码复杂度,有兴趣的话可以试试。

#define STACKMAXSIZE 10000
typedef struct {
    int *baseAdd;
    int *baseDel;
    int topAdd;
    int topDel;
} CQueue;

CQueue* cQueueCreate() {
    CQueue *obj = malloc(sizeof(CQueue));
    obj->baseAdd = malloc(sizeof(int)*STACKMAXSIZE);
    obj->baseDel = malloc(sizeof(int)*STACKMAXSIZE);
    obj->topAdd = -1;
    obj->topDel = -1;
    return obj;
}

void cQueueAppendTail(CQueue* obj, int value) {
    obj->baseAdd[++obj->topAdd] = value;
}

int cQueueDeleteHead(CQueue* obj) {
    // del栈空,且add栈非空,则将add栈元素依次出栈并压入del栈
    if(obj->topDel == -1 && obj->topAdd != -1)
    {
        while(obj->topAdd != -1)
        {
            obj->baseDel[++obj->topDel] = obj->baseAdd[obj->topAdd--];
        }
    }
    // 两栈皆空(上一步之后add栈必定空,所以可以省掉判断add栈空的条件)
    if(obj->topDel == -1 )
    {
        return -1;
    }
    // 此时,del栈必定非空,可以直接删除栈顶元素
    // 先返回值,再删除该元素
    return obj->baseDel[obj->topDel--];
}

void cQueueFree(CQueue* obj) {
    free(obj->baseAdd);
    free(obj->baseDel);
    free(obj);
}

/**
 * Your CQueue struct will be instantiated and called as such:
 * CQueue* obj = cQueueCreate();
 * cQueueAppendTail(obj, value);
 
 * int param_2 = cQueueDeleteHead(obj);
 
 * cQueueFree(obj);
*/

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值