一、最小栈
最小栈其实和栈没有什么区别的,唯一的区别在于最小栈是可以在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