实现时间复杂度为O(1)的Push,Pop,Min
2016-01-02 15:38
381 查看
定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。要求函数min、push以及pop的时间复杂度都是O(1)。
首先:要决定使用链表结构实现还是顺序结构实现,对于顺序结构实现,当数据满的情况下进行Push时,需要开辟新的数组,进行复制,因此不能保证Push的时间复杂度为O(1);链表结构能够保证Push和Pop的时间复杂度为O(1)。
思路:我们需要一个辅助栈。每次push一个新元素的时候,同时将最小元素(或最小元素的位置。考虑到栈元素的类型可能是复杂的数据结构,用最小元素的位置将能减少空间消耗)push到辅助栈中;每次pop一个元素出栈的时候,同时pop辅助栈。
首先:要决定使用链表结构实现还是顺序结构实现,对于顺序结构实现,当数据满的情况下进行Push时,需要开辟新的数组,进行复制,因此不能保证Push的时间复杂度为O(1);链表结构能够保证Push和Pop的时间复杂度为O(1)。
思路:我们需要一个辅助栈。每次push一个新元素的时候,同时将最小元素(或最小元素的位置。考虑到栈元素的类型可能是复杂的数据结构,用最小元素的位置将能减少空间消耗)push到辅助栈中;每次pop一个元素出栈的时候,同时pop辅助栈。
#pragma once #include<iostream> #include<assert.h> #include<string> using namespace std; template<class T> class Stack { public: Stack() :_array( NULL) , _size(0) , _capacity(0) {} Stack(const Stack< T>& s ) :_array( new T [s._capacity]) , _size( s._size) , _capacity( s._capacity) { for (int i = 0; i < s._size; ++i) { _array[i] = s._array[i]; } } Stack& operator=(Stack s) { swap(_array, s._array); swap(_size, s._size); swap(_capacity, s._capacity); return *this ; } ~Stack() { //cout << "~Stack()" << endl; delete[] _array; _size = _capacity = 0; } void Push(const T& x) { _CheckCapacity(); _array[_size++] = x; } void Pop() { assert(!IsEmpty()); --_size; } bool IsEmpty() { return _size == 0; } bool IsFull() { return _size == _capacity; } size_t Size() { return _size; } const T & Top() { return _array[_size - 1]; } protected: void _CheckCapacity() { if (_size == _capacity) { _capacity = 2 * _capacity + 3; T* tmp= new T[_capacity]; if (_array) { for (int i = 0; i < _size; ++i) { tmp[i] = _array[i]; } delete[] _array; } _array = tmp; } } public: T *_array; size_t _size; size_t _capacity; }; //存储元素,保证Min.Top()是最小元素 template<class T> class M { public: void PUSH(const T& x) { _Simple.Push( x); if (_Min.Size() == 0) { _Min.Push( x); } else { if (x <= _Min.Top()) _Min.Push( x); } } void POP() { assert((!_Simple.IsEmpty()) && (!_Min.IsEmpty())); if(_Min.Top()==_Simple.Top()) _Min.Pop(); _Simple.Pop(); } const T & Min() { return _Min.Top(); } protected: Stack<T > _Min;//存到目前为止最小元素 Stack<T > _Simple; }; //Min存储Simple中最小元素下标 template<class T> class S_M { public: S_M() {} ~S_M() {} void PUSH(const T& x) { _Simple.Push( x); if (_Min.Size() == 0) { _Min.Push(_Simple.Size() - 1); } else { if (x > _Simple._array[_Min.Size() - 1]) { _Min.Push(_Min.Top()); } else { _Min.Push(_Simple.Size() - 1); } } } void POP() { assert((!_Simple.IsEmpty()) && (!_Min.IsEmpty())); _Simple.Pop(); _Min.Pop(); } T& Min() { return _Simple._array[_Min.Top()]; } protected: Stack<T > _Min;//存到目前为止最小元素下标 Stack<T > _Simple; }; //测试用例 void Test1() { S_M<int> s1; s1.PUSH(1); cout<<s1.Min() << endl; } void Test2() { S_M<int> s1; s1.PUSH(1); s1.PUSH(2); cout << s1.Min() << endl; } void Test3() { S_M<int> s1; s1.PUSH(5); s1.PUSH(4); s1.PUSH(3); s1.PUSH(2); s1.PUSH(2); cout << s1.Min() << endl; } void Test4() { S_M<int> s1; s1.PUSH(3); s1.PUSH(6); s1.PUSH(2); s1.PUSH(1); s1.PUSH(0); cout << s1.Min() << endl;//0 s1.POP(); cout << s1.Min() << endl;//1 s1.POP(); cout << s1.Min() << endl;//2 s1.POP(); cout << s1.Min() << endl;//3 s1.POP(); cout << s1.Min() << endl;//3 } void Test5() { M<int> s1; s1.PUSH(3); s1.PUSH(6); s1.PUSH(2); s1.PUSH(1); s1.PUSH(0); cout << s1.Min() << endl;//0 s1.POP(); cout << s1.Min() << endl;//1 s1.POP(); cout << s1.Min() << endl;//2 s1.POP(); cout << s1.Min() << endl;//3 s1.POP(); cout << s1.Min() << endl;//3 }
相关文章推荐
- 科学知识:时间复杂度计算方法
- JavaScript数组函数unshift、shift、pop、push使用实例
- PHP 用数组降低程序的时间复杂度
- JavaScript中pop()方法的使用教程
- JavaScript使用pop方法移除数组最后一个元素用法实例
- 第15话:算法的最坏情况与平均情况
- 为什么要使用栈这种数据结构
- 快速排序里的学问:信息熵
- 功放TAS5719耳机POP noise分析 对策
- STL学习记录(十五):Stack
- 我对编程中常见名词的理解
- 算法的时间复杂度和空间复杂度
- iOS 自定义动画 push/pop动画
- MAC OS的Mail使用教程(1)
- MAC OS的Mail使用教程(2)
- android中在广播中弹出pop框的局限性
- Complexity is The Enemy
- 时间复杂度和空间复杂度详解(转)
- T(n)=25T(n/5)+n*n的时间复杂度
- 【转载】python模块之poplib: 用pop3收取邮件