题目:设计包含min 函数的栈。定义栈的数据结构,要求添加一个min 函数,能够得到栈的最小元素。要求函数min、push 以及pop 的时间复杂度都是O(1)。
解答:开始的时候很容易想到一个方法就是在栈结构中增加一个变量用来记录当前栈中最小元素的值minData,这样在push的时候更新这个minData值,那么在min函数和push函数时间复杂度确实为O(1),但是有一个问题,在pop的时候,如何更新这个minData的值?如果pop的时候正好是这个minData,那么剩余栈中的最小值如何知道,没办法知道。所以显然这种简单的想法是不行的,必须设计其他的结构。
原来的简单栈中,每一个数据元素只包括一个数据,为了适应这种min函数的要求,那么必须在栈结构中存储最小值minData,但是只是在整个栈中加一个minData,pop操作之后不能更新。所以可以想到在每个数据元素中加一个min变量,用于存储当前位置到栈底所有元素的最小值,这样一来,即使pop了栈顶元素,下一个元素的min存储的是剩余元素的最小值,所以可以满足min,push,pop的时间复杂度都是O(1)的要求。
如下图所示为栈的结构,比如依次push 7,5,3,-1,9,10,10到栈中,那么相应的元素的min值是7,5,3,-1,-1,-1,-1。
以下为实现代码
// 栈元素结构
struct MinStackElement {
int data; // 数据
int min; // 当前位置到栈底的最小值
};
// 栈结构
struct MinStack {
MinStackElement *pData;
int size;
int top;
};
// 初始化栈
MinStack MinStackInit(int maxSize) {
MinStack stack;
stack.size = maxSize;
stack.pData = (MinStackElement*) malloc(sizeof(MinStackElement)*maxSize);
stack.top = 0;
return stack;
}
// 释放栈内存
void MinStackFree(MinStack stack) {
free(stack.pData);
}
// 压栈操作,压栈的同时设置元素的min值
void MinStackPush(MinStack *stack, int d) {
if (stack->top == stack->size)
cout << "栈已满" << endl;
MinStackElement p;
p.data = d;
p.min = (stack->top==0?d:stack->pData[stack->top-1].data);
if (p.min > d)
p.min = d;
stack->pData[stack->top] = p;
stack->top ++;
}
// 出栈操作
int MinStackPop(MinStack *stack) {
if (stack->top == 0)
cout << "空栈" << endl;
return stack->pData[--stack->top].data;
}
// 最小值函数
int MinStackMin(MinStack stack) {
if (stack.top == 0)
cout << "空栈" << endl;
return stack.pData[stack.top-1].min;
}
int main()
{
// 初始化栈
MinStack stack = MinStackInit( 50 );
// 将元素压入栈中
MinStackPush(&stack, 10);
MinStackPush(&stack, 9);
MinStackPush(&stack, -1);
MinStackPush(&stack, 2);
MinStackPush(&stack, 5);
MinStackPush(&stack, 10);
// 出栈元素
cout << MinStackPop(&stack) << endl;
// 找出最小元素
cout << MinStackMin(stack) << endl;
system( "pause" );
return 0;
}