您的位置:首页 > 运维架构

实现时间复杂度为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辅助栈。
#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
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Pop 复杂度 实现时间