自定义栈-pop-push-min-时间复杂度都为O(1)

1. 简述

    首先要决定使用链表结构实现还是顺序结构实现,对于顺序结构实现,当数据满的情况下进行Push时,需要开辟新的数组,进行复制,因此不能保证Push的时间复杂度为O(1);链表结构能够保证Push和Pop的时间复杂度为O(1)。Min的时间复杂度也要求O(1),通过空间换时间,分别记录链表,当包含一个节点时,最小值所在的节点,当包含两个节点时,最小值所在的节点,等等,直到所有节点时,最小值所在的节点。这样相当于两个链表,一个链表保存数值,另一个链表保存第一个链表中,对应节点范围内的最小值所在节点。

2. 实现

#include <iostream>
using namespace std;

// 友元,链接结构 
template<class T>
class Stack;

template
<class T>
class Node {
  friend 
class Stack<T>;
private:
  T data;
  Node
<T>* link;
};

template
<class T>
class MinNode {
  friend 
class Stack<T>;
private:
  Node
<T>* min_node;
  MinNode
<T>* link;
};

template
<class T>
class Stack {
private:
  Node
<T>* head;
  MinNode
<T>* min_head;
public:
  Stack(): head(
0),min_head(0) { }
  
~Stack() {
    Node
<T>* tmp;
    
while(head) {
      tmp 
= head->link;
      delete head;
      head 
= tmp;
    }
    tmp 
= 0;
    MinNode
<T>* min_tmp;
    
while(min_head) {
      min_tmp 
= min_head->link;
      delete min_head;
      min_head 
= min_tmp; 
    }
    min_tmp 
= 0;
  }
  Stack
<T>& Push(const T& data) {
    Node
<T>* tmp = new Node<T>;
    tmp
->data = data;
    tmp
->link = head;
    head 
= tmp;
    MinNode
<T>* min_tmp = new MinNode<T>;
    
if(min_head > 0 && min_head->min_node->data < head->data)
      min_tmp
->min_node = min_head->min_node; 
    
else
      min_tmp
->min_node = head; 
    min_tmp
->link = min_head;
    min_head 
= min_tmp;
    
return *this;
  }
  Stack
<T>& Pop() {
    assert(head 
> 0);
    Node<T> *tmp = head->link;
    delete head;
    head = tmp;
    tmp = 0;
    MinNode<T> *min_tmp = min_head->link;
    delete min_head;
    min_head = min_tmp;
    min_tmp = 0;
    
return *this;
  }
  
void Min(T& data) {
    assert(head 
> 0);
    data 
= min_head->min_node->data;
  }
};


int main() {
  Stack
<int> stack;
  
int min;
  
int array[10= {3,4,5,6,7,2,1,0,9,8};
  
for(int i=0; i<10; i++) {
    stack.Push(array[i]);
    stack.Min(min);
    cout 
<< min << endl;
  }
  system(
"PAUSE");
  
return 0;
}

3. 说明

    · 对于Node, MinNode这样的节点类,把Stack声明为其友元,方便直接使用节点类的私有成员。
    · Push和Pop返回值类型为Stack<int>&,这样做是为了实现stack.push(1).push(2).push(3);这样调用方式。
    · 在参考资料中,有一份使用deque来实现内部结构的实现方式。

4. 参考

    程序员面试题精选100题(02)-设计包含min函数的栈
    http://zhedahht.blog.163.com/blog/static/25411174200712895228171/

posted @ 2011-08-12 14:52  xiaodongrush  阅读(1525)  评论(1编辑  收藏  举报