?
如何使用栈“先进后出的特性如何巧妙地借助辅助栈如何在结构体中定义可共享的静态成员变量
题目
看似很简单的求最小值函数,思路有很多很多。笔者首先想到每次push入栈都进行一次排序,使这个栈的栈顶永远是最小元素,然后就发现这是一个很蠢很蠢的想法,第一这样做会改变了栈的结构,第二不满足题目对时间复杂度的要求。 愚蠢归愚蠢,还是有点用的。既然不能改变原来栈的结构,那为何不弄俩栈呢?辅助栈的想法由此而出。 接下来是时间复杂度的问题,显然每次都进行排序是不可行的了,那么是否可以记录保存每个最小值的下一个最小值呢,也就是说,当我当前这个最小值被pop出去后,我要知道下一个最小值是哪个。这时栈的【先进后出】特性就派上用场了。
头脑风暴到此结束。下面是具体思路 牢牢把握住栈【先进后出】的特性,模拟各种实际情况,得出算法
辅助栈: 栈结构体中添加一个辅助栈,这里称为【最小值栈】,存储最小值的历史记录,所以该最小值栈的栈顶即为当前栈的最小元素
算法实现: --push 当push进来的元素值大于、等于最小值栈的栈顶,最小值栈不变,因为根据栈的特性,只有当前最小值元素上面的所有元素都出去的时候,该最小值元素才能pop出去,否则该最小值元素用于是最小值。
反之,当push进来的元素值小于最小值栈的栈顶,则将该元素放进最小值栈。
--pop 当pop出去的元素不是最小值栈栈顶,则最小值栈不变
如果pop出去的值为当前最小值,则最小值栈也pop出一个元素,此时最小值栈的栈顶就是下一个最小值元素
源代码
#include
#include
#include
using namespace std; /** 题目: 定义栈的数据结构 要求添加一个min函数,找出栈的最小元素 要求min、push、pop函数的时间复杂度都为O(1) 思路 牢牢把握住栈【先进后出】的特性,模拟各种实际情况,得出算法 栈结构体中添加一个辅助栈,这里称为【最小值栈】,存储最小值的历史记录 所以该最小值栈的栈顶即为当前栈的最小元素 当push进来的元素值大于、等于最小值栈的栈顶,最小值栈不变 因为根据栈的特性,只有当前最小值元素上面的所有元素都出去的时候,该最小值元素才能pop出去 反之,则将该元素放进最小值栈 当pop出去的元素不是最小值栈栈顶,则最小值栈不变 反之,最小值栈pop出栈顶 这样如果pop出去的值为当前最小值,则最小值栈也pop出一个元素 此时最小值栈的栈顶就是下一个最小值元素 */ /* 创建栈结点结构体 value 值 nextNode 下一个结点 push() 入栈函数 pop() 出栈函数 min() 求最小值函数 push2() 入栈并且求最小值 pop2() 出栈并且求最小值 */ struct StackNode{ int value; static StackNode * minNode; StackNode * nextNode; /** push() 入栈函数 value 入栈的值 返回 栈顶 */ StackNode * push(int value){ StackNode * top = new StackNode(); if(NULL!=this){ top=this; StackNode * push = new StackNode(); push->value=value; push->nextNode=top; top=push; }else{ top->nextNode=NULL; top->value=value; } cout<<入栈,value=<
value<
nextNode; } else{ cout<<栈已经为空<
value){ cout<<最小值栈入栈<
push(value); } }else{ //空,则直接放进去 cout<
push(value); } }else{ //pop //非空且pop的值等于最小值,则最小值栈pop if((NULL!=minNode)&&(minNode->value==value)){ cout<<最小值栈出栈<
pop(); } } if(NULL!=minNode) cout<<现在栈的最小值value=<
value<
push(value); this->min(true,value); return node; } //pop+min StackNode* pop2(){ int value = this->value; StackNode* node=this->pop(); this->min(false,value); return node; } }; //结构体静态变量初始化! StackNode * StackNode::minNode = NULL; StackNode * stack; void main() { stack=stack->push2(5); stack=stack->push2(2); stack=stack->push2(4); stack=stack->push2(1); stack=stack->push2(1); while(NULL!=stack){ stack=stack->pop2(); } system(pause); }
效果图
总结,所有与栈有关的题目,都记住这四个字——”先进后出“
?