转载并参考July的博客http://topic.csdn.net/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"); }