编程之美系列之栈和队列2—在O(1)的时间内得到队列的最大或者最小值

来源:互联网 发布:java前景如何 编辑:程序博客网 时间:2024/06/07 08:20

上一篇博客http://blog.csdn.net/kay_zhyu/article/details/8869542中提到,在O(1)的时间内取得栈的最大或者最小值,作法是利用一个辅助栈去动态的维护这个最小值。但是如果要在O(1)的时间内取得队列的最小值,那这就有点难办的吧。毕竟队列的操作特点是先进先出,跟栈的完全相反的,我们没办法像栈那要用一个动态的数组去维护这个最小值。怎么办呢?既然栈的最小值是很好维护的,那么有没有可以用栈来模拟队列呢?答案是肯定的啦!用栈模拟队列,那么就利用前面讲过的类似的思想就可以在O(1)的复杂度里面得到最小值了。
怎么用栈来模拟队列?这里需要用到两个栈,在stack1里面加元素,然后出栈的时候,首先看stack2里面有没有元素,如果有,直接将stack2里面的元素出栈,如果没有,OK,把stack1里面的数据依次pop掉,然后压入stack2中,然后stack2的栈顶元素出栈就可以了。那么,stack2和stack1中元素的关系就是,stack2中的元素一定比stack1中的元素先进队列,并且stack2中元素的进队列顺序是:顶早底晚,而stack1中元素的进队列顺序是:顶晚低早。OK,搞清这个关系,那就可以把这个模拟队列中的元素打印出来啦~~
时间分析:由于每个元素从进队列到出队列,它们经过的操作是:push到stack1中->从stack1中pop,然后push到stack2中->从stack2中pop。OK,那push,pop的时间复杂度都是O(1)了。对于队列的最小值,那就是两个辅助栈栈顶元素的最小值,同样是O(1)的操作。我得意的笑~~~得意的笑~~~~~(各位大爷转载请注明出处哦:
http://blog.csdn.net/kay_zhyu/article/details/8869641,小女子在此拜谢~~)OK,给上代码:

#include<stdio.h>const int N = 30;const int Inf = 1e5;int stack1[N];//从stack1顶进int stack2[N];//从stack2顶出int top1;int top2;int MinStack1[N];int MinStack2[N];inline int min(const int a, const int b){return a < b ? a : b;}//往栈里面加元素,其实这个函数是在上一节里面定义的函数,直接拿过来就可以用了void Add(int *stack, int *MinStack, int &top, int v){if(top > -1){stack[++top] = v;MinStack[top] = min(MinStack[top - 1], v);}elsestack[top] = MinStack[++top] = v;}//往队列里面加元素void Push(int v){Add(stack1, MinStack1, top1, v);}//删除队列头的元素void Pop(){if(top2 > -1)--top2;else{while(top1 > 0){Add(stack2, MinStack2, top2, stack1[top1]);--top1;}top1 = -1;}}//打印队列里面的元素void Print(){//stack2从栈顶到底if(top2 > -1){for(int i = top2; i >= 0; --i)printf("%d ", stack2[i]);}//stack1从栈底到顶if(top1 > -1){for(int i = 0; i <= top1; ++i)printf("%d ", stack1[i]);}}//获得队列的最小值int GetMinOfQueue(){int Min = Inf;if(top1 > -1)Min = MinStack1[top1];if(top2 > -1)Min = min(Min, MinStack2[top2]);return Min;}int main(){int IsPush,i,v;int Min;top1 = top2 = -1;printf("输入操作选项:\n0 删除栈顶元素 1 增加元素 其它 得到最小值 EOF 退出:");while(scanf("%d", &IsPush) != EOF){if(IsPush == 1){printf("输入要添加的数:");scanf("%d", &v);Push(v);}else if(!IsPush){Pop();}else{Min = GetMinOfQueue();if(Min < Inf){Print();printf("\n最小值为:%d\n", Min);}elseprintf("空队列\n");}printf("输入操作选项:\n0 删除栈顶元素 1 增加元素 其它 得到最小值 EOF 退出:");}//end while}
原创粉丝点击