<原创,请勿用于商业用途,有问题请联系:luozhaowork@163.com
/ 转载请注明链接:http://blog.csdn.net/luozhaowork/article/details/10394829>
-----------------------------------------------------------------------------------
2、如题 ,设计包含min函数的栈
首先给大家介绍下栈的概念,栈也是一种线性表,和顺序表类似,只不过栈是一种插入和删除元素只能在头部进行的特殊线性表,元素的操作顺序是:后进先出(LIFO)。
栈的实现方式有许多,你可以通过普通的数组来实现,或者通过链表来实现,具体采用哪种方式,取决于具体的问题要求。
由于栈本身的push和pop操作的时间复杂度就是O(1),所以需要考虑的问题就是如何设计一个min函数,是得每次找到最小元素的时间复杂度也是O(1).
思考一下,下图为栈的数据操作示意图。
在网上查阅了些资料,大部分提出的方法是添加一个辅助栈,用此栈保存最小元素,push v,如果v小于辅助栈顶元素,则v同时入栈和辅助栈;否则,直接入栈。进行pop v时,如果v和当前辅助栈顶元素相等,则辅助栈顶元素也弹出,这样的情况下,辅助栈顶保存的始终是当前栈中的最小值。这样就能满足min函数的O(1)的时间复杂度的要求。
先给出具体步骤:
1)初始化stack ,minstack;
2)push v->stack,比较v和当前minstack栈顶元素的大小。
2.1:如果v > pop(minstack),v入stack
2.3: 如果v <= pop(minstakck),v如stack和minstack
3)pop v,如果,比较v和minstack栈顶元素的大小
3.1:如果v > pop(minstack),则v出stack。
3.2:如果v = pop(minstack),stack和minstack同时弹出栈顶元素。
----------------------------------------------------------------------------------------
分析步骤完成,接下来看代码实现。
/* 堆栈的初始大小 */
const int SIZE = 10;
int stack[SIZE];
int top;
/* 辅助栈 */
int minstack[SIZE];
int mintop;
/* 初始化两个栈 */
void init(int *top,int *mintop)
{
*top = 0;
*mintop = 0;
}
/* 入栈操作 */
void push(int *s,int *ms, int *top,int *mintop, int element)
{
if((*top)++ > SIZE || (*top) < 0)
return;
s[(*top)++] = element;
if(element <= ms[*mintop]) {
if((*mintop) > SIZE || (*mintop) < 0) return;
ms[(*mintop)++] = element;
}
}
/* 出栈操作 */
int pop(int *s,int *ms, int *top, int *mintop)
{
if((*top) < 0 || (*mintop) < 0 || (*top) > SIZE || (*mintop) > SIZE ) {
fprintf(stderr,"索引错误!\n");
exit(1);
}
if(s[--(*top)] == ms[--(*mintop)]) {
ms[--(*mintop)];
return s[--(*top)];
}
else
if(s[--(*top)] < ms[--(*mintop)]) {
fprintf(stderr,"数据错误!\n");
exit(1);
}
else
return s[--(*top)];
}
/* 获取栈中最小值的函数 */
int min()
{
if(--(*mintop) < 0 || --(*mintop) > SIZE) {
fprintf(stderr,"索引错误!\n");
exit(1);
}
return minstack[--(*mintop)];
}