簡單來說,棧是一種特殊的線性表,只允許在固定一端(棧頂)進行插入和刪除元素的操作。因此棧又被稱爲後進先出的線性表。下面就來看看它可以進行哪些基本的操作。在進行擴容時,如果是對棧中基本數據類型的操作我們使用淺拷貝memcpy,否則用=進行拷貝,所以在這裏用到了類型萃取。下面看一下代碼實現。
/////////////////////實現Stack的基本操作//////////////////////
////////////////////////擴容時 類型萃取////////////////////
struct _TrueType
{
static bool Get()
{
return true;
}
};
struct _FalseType
{
static bool Get()
{
return false;
}
};
template<typename T>
struct TypeTraits
{
typedef _FalseType IsPOD;
};
template<>
struct TypeTraits<int>
{
typedef _TrueType IsPOD;
};
template<>
struct TypeTraits<float>
{
typedef _TrueType IsPOD;
};
template<>
struct TypeTraits<double>
{
typedef _TrueType IsPOD;
};
template<>
struct TypeTraits<long>
{
typedef _TrueType IsPOD;
};
template<>
struct TypeTraits<char>
{
typedef _TrueType IsPOD;
};
template<typename T>
class Stack
{
public:
Stack(size_t capacity = 10)
:_capacity(capacity)
{
_pData = NULL;
_size = 0;
}
Stack(const Stack<T>& s)
{
_pData = s._pData;
_size = s._size;
_capacity = s._capacity;
}
Stack<T>& operator=(const Stack<T>& s)
{
if(this != &s)
{
_pData = s._pData;
_size = s._size;
_capacity = s._capacity;
}
return *this;
}
void Push(const T& x)
{
_CheckCapacity();
_pData[_size++] = x;
}
void Pop()
{
assert(_size);
--_size;
}
size_t Size()const
{
return _size;
}
T& Top()
{
return _pData[_size-1];
}
const T& Top()const
{
return _pData[_size-1];
}
bool Empty()const
{
return _size==0;
}
private:
void _CheckCapacity()
{
if(_size == capacity)
{
T* temp = new[_capacity*2+2];//申請空間 注意要加個常數
if(TypeTraits<T>::IsPOD::Get())//如果爲POD類型
{
memcpy(temp, _pData, sizeof(T)*_size);//用memcpy拷貝元素
}
for(int idx = 0; idx < _size; idx++)//不是POD類型則 用for循環一個一個拷貝元素
{
temp[idx] = _pData[idx];
}
delete[] _pData;//釋放舊空間
_pData = temp;//指向新空間
}
_capacity = _capacity*2+2;//容量變爲新的容量
}
T* _pData;
size_t size;
size_t capacity;
};