栈和队列面试题

一、最小栈
最小栈其实和栈没有什么区别的,唯一的区别在于最小栈是可以在O(1)时间内得到当前的栈空间里,最小的值。解决这个问题提供两种方法:
Round1:
创建一个辅助栈,比较当前元素和辅助元素栈顶元素的大小 ,如果大于辅助栈栈顶元素,则不理会,反之则需要压入辅助栈。此时辅助栈的栈顶元素就是该栈的最小值。
代码实现如下(栈的操作在可参考前面写的博客–栈的实现):

void SqStackMin1(SqStack *sq1,SqStack *sq2,int flag,SqStackType value){
    if(sq1 == NULL || sq2 == NULL){
        return;                                                                                                                                                   
    }
    if(flag == 1){
        if(sq1 -> size == 1){
            SqStackPush(sq2,value);
        }
        //比较当前元素和辅助元素栈顶元素的大小
        //如果大于辅助栈栈顶元素,则不理会
        //反之则需要压入辅助栈
        else{
            SqStackType cur1 = SqStackTopValue(sq2);
            if(value > cur1){
                return;
            }
            else{
                SqStackPush(sq2,value);
            }
        }
    }
    else if(flag == 0){
        SqStackType cur2 = SqStackTopValue(sq2);
        if(value > cur2){
            return;
        }else{
            SqStackPop(sq2);
        }
    }
}
void SqStackPush1(SqStack *sq1, SqStack *sq2, SqStackType value){
    if(sq1 == NULL || sq2 == NULL){
        return;
    }
    if(sq1 -> size > sq1 -> capacity){
        SqStackResize(sq1);
    }
    sq1 -> data[sq1 -> size] =  value;
    sq1 -> size++;
    SqStackMin1(sq1,sq2,1,value);

}
void SqStackPop1(SqStack *sq1, SqStack *sq2){
    if(sq1 == NULL || sq2 == NULL){
        return;
    }
    if(sq1 -> size == 0){
        return;
    }
    SqStackType tmp = SqStackTopValue(sq1);
    SqStackMin1(sq1,sq2,0,tmp);
    sq1 -> size--;
}

Round2:
既然我们需要在O(1)时间内得到当前的栈空间里,最小的值,我们可以把最小的值放在栈顶即可实现要求,但是这样就破坏了入栈顺序,那如何实现?
我们可以每次入栈的时候入两次,第一次入栈是需要入栈的值,第二次入栈的元素和上次(本两次入栈的前一次)的元素进行比较,如果比其大,则第二次入栈的元素为上一次两次入栈第二次的元素,如果小,第二次入栈的元素就是第一次入栈的元素的值。出栈的时候就需要每次出栈两次。说的有些绕,可以看看代码来理解。
代码实现如下:

void SqStackPush2(SqStack *sq,SqStackType value){
    if(sq == NULL){
        return;
    }
    if(sq -> size == 0){
        sq -> data[sq -> size] = value;
        sq -> size++;
        sq -> data[sq -> size] = value;
        sq -> size++;
    }
    SqStackType tmp = SqStackTopValue(sq);
    if(value > tmp){                                                                                                                                              

        SqStackPush(sq,value);
        SqStackPush(sq,tmp);
    }else{
        SqStackPush(sq,value);
        SqStackPush(sq,value);
    }
}
void SqStackPop2(SqStack *sq){
    if(sq == NULL){
        return;
    }
    if(sq -> size == 0){
        return;
    }
    SqStackPop(sq);
    SqStackPop(sq);
}
SqStackType SqStackGetTop(SqStack* sq){
    //栈顶元素是最小值
    SqStackType min = SqStackTopValue(sq);
    return min;
}

二、两个栈实现一个队列
栈和队列的根本区别就是,栈是后进先出,队列是先进先出。因此用两个栈实现一个队列,就是需要用两个栈来实现先进先出这种情况,那如何实现呢?
首先我们定义两个栈input和output,实现入队操作是非常简单的,只要入input栈即可,当实现出队列的时候,我们首先将input内的元素一次出栈,然后依次入栈output,然后再让output出栈,这样就实现了队列的出队列操作。

具体代码实现如下:

typedef SqStackType QueueType;

typedef struct Queue{
    SqStack input;
    SqStack output;
}Queue;

void QueueInit(Queue* q){ 
    if(q == NULL){
        return;
    }   
    InitSqStack(&q -> input);
    InitSqStack(&q -> output);
}

void QueuePush(Queue* q, QueueType value){
    if(q == NULL){
        return;
    }   
    QueueType tmp;
    while(SqStackTop(&q -> output, &tmp)){
        SqStackPop(&q -> input);
        SqStackPush(&q -> output, tmp);
    }   
    SqStackPush(&q -> input, value);
}

void QueuePop(Queue* q){
    if(q == NULL){
        return;
    }
    QueueType tmp;
    while(SqStackTop(&q -> input, &tmp)){
        SqStackPop(&q -> output);
        SqStackPush(&q -> input, tmp);
    }
    SqStackPop(&q -> output);
}

int QueueFront(Queue* q, QueueTyp
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值