LC-OJ栈实现队列

文章介绍了如何使用两个栈来实现队列的功能,包括创建、插入、删除和判断空操作。在栈中,数据的插入和删除都在栈顶进行,而队列需要在队首删除,队尾插入。通过在插入时使用一个栈,在删除时将另一个栈的内容转移过来,解决了这个问题。
摘要由CSDN通过智能技术生成

栈实现队列部分功能

OJ链接:https://leetcode.cn/problems/implement-queue-using-stacks/

这里我们要使用栈来实现队列的部分功能时,首先我们需要一个栈。

这里就让我们来当个cv工程师吧,毕竟C语言oj时还是需要手搓的。

代码

typedef struct Stack
{
    int* data;
    int capacity;
    int size;
}Stack;
void STpush(Stack* ST,int x);
void STinit(Stack* ST);
void STpop(Stack*ST);
void STbuyNode(Stack*ST)
{
    int* ptr=(int*)malloc(sizeof(int)*20);
    assert(ptr);
    ST->data=ptr;
    ST->capacity=20;
}
void STinit(Stack* ST)
{
    STbuyNode(ST);
    ST->size=-1;
};
void STpush(Stack* ST,int x)
{
    if(ST->capacity==ST->size)
    {
        int*ptr=(int*)realloc(ST->data,sizeof(int)*ST->capacity*2);
        assert(ptr);
        ST->data=ptr;
        ST->capacity*=2;
    }
    ST->size++;
    ST->data[ST->size]=x;
}
void STpop(Stack*ST)
{
    ST->data[ST->size]=0;
    ST->size--;
}

这里当cv工程师还是很爽的。

接下来有了栈,就是如何用栈去实现对垒的功能了

typedef struct 
{

} MyQueue;
void myQueueFree(MyQueue* obj);
bool myQueueEmpty(MyQueue* obj);
int myQueuePeek(MyQueue* obj);
int myQueuePop(MyQueue* obj);
void myQueuePush(MyQueue* obj, int x);
MyQueue* myQueueCreate();

即:
队列的创建
队列首元素访问
队列的插入
队列的数据删除
队列的判断是否为空
队列的销毁

我们都知道栈 是只进行栈顶的插入和删除数据
而队列则是 队首进行删除,队尾进行插入数据

当我们要用栈实现队列的插入操作时
直接在栈顶加入就行
但是当我们要用栈实现队列的删除时,问题就麻烦了
对于队列来说,需要进行删除的数据是栈底,而队列只能对栈顶数据进行的操作。

这个其实就是这个oj的核心问题,如果想清楚了,那整道题就迎刃而解了。

这里的思路就是,一个栈不行,那就两个栈来实现。
思路图:请添加图片描述

设置两个栈,一个为添加栈,一个为删除栈,两个栈的元素进行相互处理,这样就可以实现队列的效果了。

队列的创建

typedef struct 
{
    Stack stack_del;
    Stack stack_add;
} MyQueue;
MyQueue* myQueueCreate() 
{
    MyQueue*ptr=malloc(sizeof(MyQueue));
    assert(ptr);
    STinit(&ptr->stack_add);
    STinit(&ptr->stack_del);
    return ptr; 
}

经过我们刚刚的分析,队列由插入栈和删除栈组成。
所以队列的定义是两个栈。

队列的判断空和销毁

bool myQueueEmpty(MyQueue* obj) 
{
    if(obj->stack_add.size==-1&&obj->stack_del.size==-1)
    {
        return true;
    }
    else
        return false;
}
void myQueueFree(MyQueue* obj) 
{
    free(obj->stack_add.data);
    free(obj->stack_del.data);
    free(obj);
}

这里我们栈中的size初始值为-1,所以两个栈size都为-1时,则队列为空。

而free则是对队列的两个栈进行free,再将队列结构体进行置空
其实应该要将obj进行置空的,但是这个oj时接口型,所以就不管了。

队列的插入和删除

插入

void myQueuePush(MyQueue* obj, int x) 
{
  if (myQueueEmpty(obj)== true)
    {
        STpush(&obj->stack_add, x);
    }
    else
    {
        if(obj->stack_add.size == -1)
        {
            while (obj->stack_del.size != -1)
            {
                STpush(&obj->stack_add, obj->stack_del.data[obj->stack_del.size]);
                STpop(&obj->stack_del);
            }
        }
        STpush(&obj->stack_add, x);
    }
}

首先对队列进行判空
如果为空

直接在插入栈进行数据插入就行。

当队列不为空时
如果插入栈不为空,则直接插入在插入栈

如果插入栈为空,则将删除栈的所有数移至插入栈,再进行插入。

删除

int myQueuePop(MyQueue* obj) 
{
    if(myQueueEmpty(obj)==true)
    {
        return NULL;
    }
    else
    {
        if(obj->stack_del.size==-1)
        {
            while(obj->stack_add.size!=-1)
            {
                STpush(&obj->stack_del,obj->stack_add.data[obj->stack_add.size]);
                STpop(&obj->stack_add);
            }
        }
        int x=obj->stack_del.data[obj->stack_del.size];
        STpop(&obj->stack_del);
        return x;
    }
}

首先判断队列是否为空
队列为空
返回空
队列不为空
判断插入栈是否为空
为空,则直接对删除栈的数据进行出栈。
不为空,将插入栈的数据入栈至删除栈,再对删除栈,进行出栈。

整体代码

typedef struct Stack
{
    int* data;
    int capacity;
    int size;
}Stack;
typedef struct 
{
    Stack stack_del;
    Stack stack_add;
} MyQueue;
void myQueueFree(MyQueue* obj);
void STpush(Stack* ST,int x);
void STinit(Stack* ST);
void STpop(Stack*ST);
void myQueueFree(MyQueue* obj);
bool myQueueEmpty(MyQueue* obj);
int myQueuePeek(MyQueue* obj);
int myQueuePop(MyQueue* obj);
void myQueuePush(MyQueue* obj, int x);
MyQueue* myQueueCreate();
void STbuyNode(Stack*ST)
{
    int* ptr=(int*)malloc(sizeof(int)*20);
    assert(ptr);
    ST->data=ptr;
    ST->capacity=20;
}
void STinit(Stack* ST)
{
    STbuyNode(ST);
    ST->size=-1;
};
void STpush(Stack* ST,int x)
{
    if(ST->capacity==ST->size)
    {
        int*ptr=(int*)realloc(ST->data,sizeof(int)*ST->capacity*2);
        assert(ptr);
        ST->data=ptr;
        ST->capacity*=2;
    }
    ST->size++;
    ST->data[ST->size]=x;
}
void STpop(Stack*ST)
{
    ST->data[ST->size]=0;
    ST->size--;
}
MyQueue* myQueueCreate() 
{
    MyQueue*ptr=malloc(sizeof(MyQueue));
    assert(ptr);
    STinit(&ptr->stack_add);
    STinit(&ptr->stack_del);
    return ptr; 
}
void myQueuePush(MyQueue* obj, int x) 
{
  if (myQueueEmpty(obj)== true)
    {
        STpush(&obj->stack_add, x);
    }
    else
    {
        if(obj->stack_add.size == -1)
        {
            while (obj->stack_del.size != -1)
            {
                STpush(&obj->stack_add, obj->stack_del.data[obj->stack_del.size]);
                STpop(&obj->stack_del);
            }
        }
        STpush(&obj->stack_add, x);
    }
}
int myQueuePop(MyQueue* obj) 
{
    if(myQueueEmpty(obj)==true)
    {
        return NULL;
    }
    else
    {
        if(obj->stack_del.size==-1)
        {
            while(obj->stack_add.size!=-1)
            {
                STpush(&obj->stack_del,obj->stack_add.data[obj->stack_add.size]);
                STpop(&obj->stack_add);
            }
        }
        int x=obj->stack_del.data[obj->stack_del.size];
        STpop(&obj->stack_del);
        return x;
    }
}
int myQueuePeek(MyQueue* obj) 
{
    if(myQueueEmpty(obj)==true)
    {
        return NULL;
    }
    else
    {
        if(obj->stack_del.size==-1)
            return obj->stack_add.data[0];
        else
            return obj->stack_del.data[obj->stack_del.size];
    }
}
bool myQueueEmpty(MyQueue* obj) 
{
    if(obj->stack_add.size==-1&&obj->stack_del.size==-1)
    {
        return true;
    }
    else
        return false;
}
void myQueueFree(MyQueue* obj) 
{
    free(obj->stack_add.data);
    free(obj->stack_del.data);
    free(obj);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想学c啊啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值