小白学C语言数据结构之栈和队列(二:例题贴)

经典题~

1.用栈的方式,实现一个队列的结构

思路

先想性质:栈是先进后出,队列是先进先出。

那用两个栈来回倒腾,是不是就可以实现队列的模式了

分两个栈,一个help栈,一个data栈。

data栈一开始进的数据是 1 2 3 4 5

输出的数据是 5 4 3 2 1

但是想要队列的结构,所以我们实际想输出的是1-2-3-4-5

那就把data栈里的data放进help栈里,再输出

pay attention!

还是有一些小细节

一旦data开始导数据,必须导空

一旦help开始倒数据,也必须倒空

不然数据就会乱掉...

代码

struct Queue{                // 队列,由data数组和help数组组成
    struct Stack data;
    struct Stack help;
};
void enqueue(struct Queue* queue, int data){
    push(&queue->data, data);         // 这边的细节在于要写 &queue->data 因为上面是指针格式
}
int dequeue(struct Queue* queue){
    if(queue ==NULL){
        return;
    }
    while(queue->data->top != NULL){        //一旦开始倒,就全部倒空到help栈里去
        push(&queue->help, pop(&queue->data));
    }                            
    int val = pop(&queue->help);    //弹help的栈顶元素
    while(queue->help->top !=NULL){    // 此时data栈为空,需要把队列恢复原本的模样,方便下一次弹出操作
        push(&queue->data, pop(&queue->help));
    }
    return val;
}

2.用队列方式,实现一个栈的结构

思路

仍旧是先想性质。 队列是先进先出,栈是先进后出....

现在有两个队列

A 1 2 3 4 5

B NULL

我要用5 4 3 2 1的次序输出,怎么办?

先把A中的1 2 3 4 挪到B数组中,然后输出A剩下的!

A 5

B 1 2 3 4

5输出掉之后 ,A变成空,再输出4

A 1 2 3

B 4 ...............依此类推

代码

struct Stack{
    struct Queue* queue1;
    struct Queue* queue2;
};
void push(struct Stack* stack, int data){
    enqueue(&stack->queue1, data);
}
int pop(struct Stack *s) {
    //将主队列中的元素全部出队并入队到辅助队列中,只留下最后一个元素
    while (!isQueueEmpty(&s->queue1)) {    // 不愧是chatgpt写的...思路好奇妙
        int value = dequeue(&s->queue1);    //先用value逐个记录值,当记录完最后一个的时候
                                                // 此时queue为空,返回这最后一个值
        if (!isQueueEmpty(&s->queue1)) {
            enqueue(&s->queue2, value);
        } else {
            //最后一个元素出队
            return value;
        }
    }
    //如果主队列为空,则辅助队列中的元素即为栈中元素
    while (!isQueueEmpty(&s->queue2)) {        //如果辅助队列不为空,就再倒回主队列
        int value = dequeue(&s->queue2);
        enqueue(&s->queue1, value);
    }
    return -1;                                 
}

3.输出栈中的最小值,且要求时间复杂度为O(1)

输出最小值很容易...

比如我把栈里的数字依次pop出来,之后再随便做个排序

思路很简单,但是不符合题目要求:时间复杂度O(1)

思路

那么这样的话思路是怎么样呢?

依旧是那个思路:辅助栈

比如这样一组数 3 4 2 7 1 0 (<-----------次序是这样,3是栈顶元素)

一开始他们在data栈中

这时候我们设置一个min栈,依次弹出data栈中的数据并放进min栈中

但是有一个小思路,就是 假设后面进这个数字比前面这个数字大的话,就不入栈,让值等于上一个

for example

3最先弹出到data栈中,下一个弹4

比较后发现4>3,于是乎 本来应该是 4 3 的min栈,现在成3 3

下一次弹2, min栈就变成2 3 3....

coding!

可以看到,这个方式没有经过遍历,时间复杂度为O(1)

代码

int minStack(struct Stack* stack){
    struct Stack* data = stack;
    struct Stack* min = NULL;
    while(data->top != NULL){    //只要data栈不是空的,就继续往下
        int val = pop(&data);
        push(&min, val);        // 第一次先把最初的栈顶元素压进去
        
        if(data->top->value <= min->top->value){
            int val2 = pop(&data);
            push(&min, val2);
        }
        else{
            data->top->value = min->top->value;
            int val2 = pop(&data);
            push(&min, val2);
        }
    }
    return min->top->value;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值