1 /*
2 定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数。在该栈中,调用min,push及pop的时间复杂度都是O(1)。
3 分析发现,可以把每次的最小元素(之前的最小元素和新压入栈的元素两者的较低值)都保存起来到另外一个辅助栈里面。举例论证。
4 首先往空的数据栈亚茹数字3,显然现在3是最小值,我们也把这个最小值压入辅助栈,接下来往数据栈中压入数字4.由于4大于之前的最小值,因此我们任然往辅助栈里压入数字数字3.第三步继续往数据栈中压入数字2.由于2小于之
前的数字3,因此我们把最小值更新为2,并把2压入辅助栈,同样压入数字1时,也要更新最小值,并把新的最小值压入辅助栈。
5 数据栈 辅助栈 最小值
6 压入3 3 3 3
7 压入4 3,4 3,3 3
8 压入2 3,4,2 3,3,2 2
9 压入1 3,4,2,1 3,3,2,1 1
10 在辅助栈的栈顶元素始终都是最低元素,当最小元素从数据栈内被弹出之后,同时弹出辅助栈的栈顶元素,此时辅助栈的新栈顶元素就是下一个最小值。
11 */
12
13 //m_data是数据栈,m_min是最小栈
2 定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数。在该栈中,调用min,push及pop的时间复杂度都是O(1)。
3 分析发现,可以把每次的最小元素(之前的最小元素和新压入栈的元素两者的较低值)都保存起来到另外一个辅助栈里面。举例论证。
4 首先往空的数据栈亚茹数字3,显然现在3是最小值,我们也把这个最小值压入辅助栈,接下来往数据栈中压入数字4.由于4大于之前的最小值,因此我们任然往辅助栈里压入数字数字3.第三步继续往数据栈中压入数字2.由于2小于之
前的数字3,因此我们把最小值更新为2,并把2压入辅助栈,同样压入数字1时,也要更新最小值,并把新的最小值压入辅助栈。
5 数据栈 辅助栈 最小值
6 压入3 3 3 3
7 压入4 3,4 3,3 3
8 压入2 3,4,2 3,3,2 2
9 压入1 3,4,2,1 3,3,2,1 1
10 在辅助栈的栈顶元素始终都是最低元素,当最小元素从数据栈内被弹出之后,同时弹出辅助栈的栈顶元素,此时辅助栈的新栈顶元素就是下一个最小值。
11 */
12
13 //m_data是数据栈,m_min是最小栈
14
14
15 template<class T>
16 void StackWithMin<T>::push(const T& value) //push函数
17 {
18 m_data.push(value);
19
20 if(m_min.size() == 0 || value < m_min.top()) //新元素是最小值,插入到最小栈中
21 m_min.push(value);
22 else
23 m_min.push(m_min.top()); //新元素不是最小值,插入最小栈的栈顶元素
24 }
25
26 template<class T>
27 void StackWithMin<T>::pop() //pop()函数
28 {
29 assert(m_data.size() > 0 && m_min.size() > 0); //
30
31 m_data.pop();
32 m_min.pop();
33 }
34
35 template<class T>
36 const T& StackWithMin<T>::Min() const //Min()函数
37 {
38 assert(m_data.size() > 0 && m_min.size() > 0);
39
40 return m_min.top(); //返回最小栈的栈顶元素
41 }
42
43
44 /*
45 不管是广度优先遍历一个有向图还是一棵树,都要用到队列。第一步我们把起始结点(对树而言是根结点)放入到队列中。接下来每一次从队列的头部取出一个结点,遍历这个结点之后把从它能到达的结点(对树而言是子结点)都
依次放入队列。我们重复这个遍历过程,知道这个队列中的结点全部被遍历为止。
46 */