您的位置:首页 > 编程语言

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

2013-04-30 15:00 288 查看
上一篇博客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
;//从stack1顶进
int stack2
;//从stack2顶出
int top1;
int top2;
int MinStack1
;
int MinStack2
;
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);
}
else
stack[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);
}
else
printf("空队列\n");
}
printf("输入操作选项:\n0 删除栈顶元素 1 增加元素 其它 得到最小值 EOF 退出:");
}//end while
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐