最小栈:有入栈,出栈,取栈顶元素,取出栈内的最小值的时间复杂度均为O(1);
有两种实现方式:
第一种:使用一个栈没入栈一个元素,都再次把最小值插入,所以每次入栈,其实要入两个元素,栈顶永远是最小值,取栈内最小值就是取栈顶元素,将9725入栈,出栈,取栈顶元素如下图:
入栈过程:
出栈:
取栈顶元素:
代码如下:
头文件MinStack1.h
#pragma once
#define MinStackMaxSize 1000
#define MinStackType char
typedef struct MinStack {
MinStackType data[MinStackMaxSize];
size_t size;
}MinStack;
void MinStackInit(MinStack* minstack); //初始化栈
void MinStackPush(MinStack* minstack, MinStackType value); //入栈
void MinStackPop(MinStack* minstack); //出栈
int MinStackTop(MinStack* minstack, MinStackType* min_value); //取栈顶元素
头文件的实现Minstack1.c
#include<stdio.h>
#include"MinStack1.h"
void MinStackInit(MinStack* minstack) {
if(minstack == NULL) {
return;
}
minstack->size = 0;
return;
}
void MinStackPush(MinStack* minstack, MinStackType value) {
if(minstack == NULL || minstack->size >= MinStackMaxSize) {
return;
}
if(minstack->size == 0) {
minstack->data[minstack->size] = value;
minstack->size++;
minstack->data[minstack->size] = value;
minstack->size++;
return;
}
MinStackType min;
min = minstack->data[minstack->size - 1] > value ? value : minstack->data[minstack->size - 1];
minstack->data[minstack->size] = value;
minstack->size++;
minstack->data[minstack->size] = min;
minstack->size++;
return;
}
void MinStackPop(MinStack* minstack) {
if(minstack == NULL || minstack->size == 0) {
return;
}
minstack->size -= 2;
}
int MinStackTop(MinStack* minstack, MinStackType* min_value) {
if(minstack == NULL || min_value == NULL) {
return 0;
}
if(minstack->size == 0) {
return 0;
}
*min_value = minstack->data[minstack->size - 1];
return 1;
}
/
//以下为测试代码
//
MinStack minstack;
void TestMinStack() {
MinStackInit(&minstack);
MinStackPush(&minstack, '9');
MinStackPush(&minstack, '5');
MinStackPush(&minstack, '7');
MinStackPush(&minstack, '2');
MinStackType top;
int ret;
ret = MinStackTop(&minstack, &top);
printf("ret expected 1, actual %d\n", ret);
printf("top expected 2, actual %c\n", top);
MinStackPop(&minstack);
ret = MinStackTop(&minstack, &top);
printf("ret expected 1, actual %d\n", ret);
printf("top expected 5, actual %c\n", top);
MinStackPop(&minstack);
ret = MinStackTop(&minstack, &top);
printf("ret expected 1, actual %d\n", ret);
printf("top expected 5, actual %c\n", top);
MinStackPop(&minstack);
ret = MinStackTop(&minstack, &top);
printf("ret expected 1, actual %d\n", ret);
printf("top expected 9, actual %c\n", top);
MinStackPop(&minstack);
ret = MinStackTop(&minstack, &top);
printf("ret expected 0, actual %d\n", ret);
MinStackPop(&minstack);
}
int main()
{
TestMinStack();
return 0;
}
实验结果:
缺点:虽然符合最小栈的要求,但是却只能得到栈中的最小值,却不能得到真正入栈的栈顶元素
第二种:使用两个栈,stack 和 min_stack , stack存放真正入栈的元素, min_stack存放stack的最小元素,所以min_stack的栈顶总是当前stack中的最小值,原理如下图:
入栈:
出栈:
取栈顶元素:
代码如下:
头文件:MinStack2.h
#pragma once
#define MinStackMaxSize 1000
#define MinStackType char
typedef struct MinStack {
MinStackType data[MinStackMaxSize];
size_t size;
}MinStack;
typedef struct MinStackByTwo {
MinStack stack;
MinStack min_stack;
}MinStackByTwo;
void MinStackInit(MinStackByTwo* minstack_bytwo); //栈的初始化
void MinStackPush(MinStackByTwo* minstack_bytwo, MinStackType value); //入栈
void MinStackPop(MinStackByTwo* minstack_bytwo); //出栈
int MinStackTop(MinStackByTwo* minstack_bytwo, MinStackType* top, MinStackType* min_value); //取栈顶元素
头文件的实现:MinStack2.c
#include<stdio.h>
#include"MinStack2.h"
void MinStackInit(MinStackByTwo* minstack_bytwo) {
if(minstack_bytwo == NULL) {
return;
}
minstack_bytwo->stack.size = 0;
minstack_bytwo->min_stack.size = 0;
return;
}
void MinStackPush(MinStackByTwo* minstack_bytwo, MinStackType value) {
if(minstack_bytwo == NULL || minstack_bytwo->stack.size >= MinStackMaxSize) {
return;
}
if(minstack_bytwo->stack.size == 0) {
minstack_bytwo->stack.data[minstack_bytwo->stack.size] = value;
minstack_bytwo->stack.size++;
minstack_bytwo->min_stack.data[minstack_bytwo->min_stack.size] = value;
minstack_bytwo->min_stack.size++;
return;
}
MinStackType min = value;
if(value >= minstack_bytwo->min_stack.data[minstack_bytwo->min_stack.size - 1]) {
min = minstack_bytwo->min_stack.data[minstack_bytwo->min_stack.size - 1];
}
minstack_bytwo->stack.data[minstack_bytwo->stack.size++] = value;
minstack_bytwo->min_stack.data[minstack_bytwo->min_stack.size++] = min;
return;
}
void MinStackPop(MinStackByTwo* minstack_bytwo) {
if(minstack_bytwo == NULL || minstack_bytwo->stack.size == 0) {
return;
}
minstack_bytwo->stack.size -= 1;
minstack_bytwo->min_stack.size -= 1;
return;
}
int MinStackTop(MinStackByTwo* minstack_bytwo,MinStackType* top_value, MinStackType* min_value) {
if(minstack_bytwo == NULL || min_value == NULL) {
return 0;
}
if(minstack_bytwo->stack.size == 0) {
return 0;
}
*min_value = minstack_bytwo->min_stack.data[minstack_bytwo->min_stack.size - 1];
*top_value = minstack_bytwo->stack.data[minstack_bytwo->stack.size - 1];
return 1;
}
/
//以下为测试代码
//
void TestMinStackByTwo() {
MinStackByTwo minstack;
MinStackInit(&minstack);
MinStackPush(&minstack, '9');
MinStackPush(&minstack, '5');
MinStackPush(&minstack, '7');
MinStackPush(&minstack, '2');
MinStackType min;
MinStackType top;
int ret;
ret = MinStackTop(&minstack, &top, &min);
printf("ret expected 1, actual %d\n", ret);
printf("top expected 2, actual %c\n", top);
printf("min expected 2, actual %c\n", min);
MinStackPop(&minstack);
ret = MinStackTop(&minstack, &top, &min);
printf("ret expected 1, actual %d\n", ret);
printf("top expected 7, actual %c\n", top);
printf("min expected 5, actual %c\n", min);
MinStackPop(&minstack);
ret = MinStackTop(&minstack, &top, &min);
printf("ret expected 1, actual %d\n", ret);
printf("top expected 5, actual %c\n", top);
printf("min expected 5, actual %c\n", min);
MinStackPop(&minstack);
ret = MinStackTop(&minstack, &top, &min);
printf("ret expected 1, actual %d\n", ret);
printf("top expected 9, actual %c\n", top);
printf("min expected 9, actual %c\n", min);
MinStackPop(&minstack);
ret = MinStackTop(&minstack, &top, &min);
printf("ret expected 0, actual %d\n", ret);
MinStackPop(&minstack);
}
int main()
{
TestMinStackByTwo();
return 0;
}
实验结果: