转载并参考July的博客http://topic.youkuaiyun.com/u/20101126/10/b4f12a00-6280-492f-b785-cb6835a63dc9.html,万分感谢!
题目:
定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。要求函数min、push以及pop的时间复杂度都是O(1)。结合链表一起做。提示:结合链表一起做。
分析:
要想求得复杂度是O(1)的算法,基本思路是设计一个辅助栈,该栈随时更新保存的当前所有数据的最小值。即一发现有更小的值,就把数据压入该辅助站中。
解一:
利用C++的Template可以增强代码的复用性。同时,结合vector类型内置的push_back(),pop_back()函数可以简化操作。
/*Title: 2.设计包含min函数的栈:解一
Author: gocode
Date: 2012-09-29*/
#include <iostream>
#include <assert.h>
#include <vector>
using namespace std;
template <typename T>
class StackSuppliedMin
{
public:
vector<T> datas; // 保存值的数据栈
vector<T> minStack; // 辅助栈,保存最小值位置,记住这里只是记录了最小值在datas的位置
// 进栈操作
void Push(T data)
{
datas.push_back(data);
if (minStack.empty() || data < datas[minStack.back()])
minStack.push_back(datas.size()-1);
}
// 出栈操作
void Pop()
{
//assert(!datas.empty());
if (!datas.empty() && datas.back() == datas[minStack.back()])
minStack.pop_back();
datas.pop_back();
}
// 返回栈顶数据值
T Peek()
{
//assert(!datas.empty());
if (!datas.empty())
return datas.back();
else
{
cout<<"Data stack is empty.";
return NULL;
}
}
// 获得最小值
T GetMinimal()
{
//assert(!datas.empty() && !minStack.empty());
if (!datas.empty() && !minStack.empty())
return datas[minStack.back()];
else
{
cout<<"Minimal stack is empty.";
return NULL;
}
}
// 列出栈里的数据
void displayStack(vector<T> theStack)
{
if (!theStack.empty())
{
for (vector<T>::iterator it = theStack.begin(); it != theStack.end(); ++it)
cout<<*it<<" ";
cout<<endl;
}
else
cout<<"No data in the stack."<<endl;
}
};
void main()
{
StackSuppliedMin<int> myStackClass;
// 推进栈,并显示变化情况
myStackClass.Push(2);
cout<<"After push "<<myStackClass.Peek()<<" the 2 stacks contain: "<<endl;
myStackClass.displayStack(myStackClass.datas);
myStackClass.displayStack(myStackClass.minStack);
cout<<endl;
myStackClass.Push(6);
cout<<"After push "<<myStackClass.Peek()<<" the 2 stacks contain: "<<endl;
myStackClass.displayStack(myStackClass.datas);
myStackClass.displayStack(myStackClass.minStack);
cout<<endl;
myStackClass.Push(4);
cout<<"After push "<<myStackClass.Peek()<<" the 2 stacks contain: "<<endl;
myStackClass.displayStack(myStackClass.datas);
myStackClass.displayStack(myStackClass.minStack);
cout<<endl;
myStackClass.Push(1);
cout<<"After push "<<myStackClass.Peek()<<" the 2 stacks contain: "<<endl;
myStackClass.displayStack(myStackClass.datas);
myStackClass.displayStack(myStackClass.minStack);
cout<<endl;
myStackClass.Push(5);
cout<<"After push "<<myStackClass.Peek()<<" the 2 stacks contain: "<<endl;
myStackClass.displayStack(myStackClass.datas);
myStackClass.displayStack(myStackClass.minStack);
cout<<endl;
cout<<"Current stacks status: "<<endl;
myStackClass.displayStack(myStackClass.datas);
myStackClass.displayStack(myStackClass.minStack);
cout<<endl;
// 弹出栈,并显示当前变化情况
cout<<"The top data in statck is: "<<myStackClass.Peek()<<endl;
myStackClass.Pop();
cout<<"After pop the minimal data: "<<myStackClass.GetMinimal()<<endl;
cout<<"After pop the 2 stacks contain: "<<endl;
myStackClass.displayStack(myStackClass.datas);
myStackClass.displayStack(myStackClass.minStack);
cout<<endl;
cout<<"The top data in statck is: "<<myStackClass.Peek()<<endl;
myStackClass.Pop();
cout<<"After pop the minimal data: "<<myStackClass.GetMinimal()<<endl;
cout<<"After pop the 2 stacks contain: "<<endl;
myStackClass.displayStack(myStackClass.datas);
myStackClass.displayStack(myStackClass.minStack);
cout<<endl;
cout<<"The top data in statck is: "<<myStackClass.Peek()<<endl;
myStackClass.Pop();
cout<<"After pop the minimal data: "<<myStackClass.GetMinimal()<<endl;
cout<<"After pop the 2 stacks contain: "<<endl;
myStackClass.displayStack(myStackClass.datas);
myStackClass.displayStack(myStackClass.minStack);
cout<<endl;
cout<<"The top data in statck is: "<<myStackClass.Peek()<<endl;
myStackClass.Pop();
cout<<"After pop the minimal data: "<<myStackClass.GetMinimal()<<endl;
cout<<"After pop the 2 stacks contain: "<<endl;
myStackClass.displayStack(myStackClass.datas);
myStackClass.displayStack(myStackClass.minStack);
cout<<endl;
cout<<"The top data in statck is: "<<myStackClass.Peek()<<endl;
myStackClass.Pop();
cout<<"After pop the minimal data: "<<myStackClass.GetMinimal()<<endl;
cout<<"After pop the 2 stacks contain: "<<endl;
myStackClass.displayStack(myStackClass.datas);
myStackClass.displayStack(myStackClass.minStack);
cout<<endl;
system("pause");
}
结果:
解二:
使用传统链表构造栈,链表节点有两个值,一个是当前节点的值,另一个是栈中最小值。这样同样能够解决问题。
/*Title: 2.设计包含min函数的栈:解二
Author: gocode
Date: 2012-09-29*/
#include <iostream>
using namespace std;
struct MinStackElement
{
int data;
int min;
};
struct MinStack
{
MinStackElement *item;
int size;
int top;
};
MinStack MinStackInit(int maxSize)
{
MinStack stack;
stack.size = maxSize;
stack.item = (MinStackElement *) malloc (sizeof(MinStackElement)*maxSize);
stack.top = 0;
return stack;
}
void MinStackFree(MinStack stack)
{
free(stack.item);
stack.size = 0; // 表示栈里数据的容量
stack.top = 0; // 表示栈顶
}
// 把数值压入栈顶
void MinStackPush(MinStack &stack, int d)
{
if (stack.top == stack.size)
{
cout<<"out of stack space."<<endl;
return;
}
// 指向栈顶,并赋值d
MinStackElement *p = &stack.item[stack.top];
p->data = d;
// 先赋值原最小值,然后和data作比较判断出当前最小值
p->min = (stack.top==0 ? d : stack.item[stack.top-1].min);
if (p->min > d)
p->min = d;
stack.top++;
}
// 弹出栈中栈顶数据
void MinStackPop(MinStack &stack)
{
if (stack.top == 0)
{
cout<<"stack is empty."<<endl;
return ;
}
--stack.top;
}
// 求得栈中当前最小值
int MinStackMin(MinStack &stack)
{
if (stack.top == 0)
{
cout<<"stack is empty."<<endl;
return NULL;
}
return stack.item[stack.top-1].min;
}
int MinStackPeek(MinStack stack)
{
if (stack.top == 0)
{
cout<<"stack is empty."<<endl;
return NULL;
}
return stack.item[stack.top-1].data;
}
// 显示栈中数据
void MinStackDisplay(MinStack stack)
{
if (stack.size == 0)
{
cout<<"stack is empty."<<endl;
return;
}
else
{
for (int i = 0; i < stack.top; i++)
{
cout<<stack.item[i].data<<" ";
}
cout<<endl;
}
}
void main()
{
MinStack thestack = MinStackInit(5);
MinStackPush(thestack, 2);
MinStackPush(thestack, 6);
MinStackPush(thestack, 4);
MinStackPush(thestack, 1);
MinStackPush(thestack, 5);
MinStackDisplay(thestack);
cout<<"Pop the value "<<MinStackPeek(thestack)<<endl;
MinStackPop(thestack);
cout<<"Minimal value is: "<<MinStackMin(thestack)<<endl;
MinStackDisplay(thestack);
cout<<"Pop the value "<<MinStackPeek(thestack)<<endl;
MinStackPop(thestack);
cout<<"Minimal value is: "<<MinStackMin(thestack)<<endl;
MinStackDisplay(thestack);
cout<<"Pop the value "<<MinStackPeek(thestack)<<endl;
MinStackPop(thestack);
cout<<"Minimal value is: "<<MinStackMin(thestack)<<endl;
MinStackDisplay(thestack);
cout<<"Pop the value "<<MinStackPeek(thestack)<<endl;
MinStackPop(thestack);
cout<<"Minimal value is: "<<MinStackMin(thestack)<<endl;
MinStackDisplay(thestack);
cout<<"Pop the value "<<MinStackPeek(thestack)<<endl;
MinStackPop(thestack);
cout<<"Minimal value is: "<<MinStackMin(thestack)<<endl;
MinStackDisplay(thestack);
system("pause");
}
结果: