棧的定義--Stack
棧只允許在末端(即是棧頂)進行插入和刪除的線性表。棧具有後進先出的特性(LIFO,Last In First Out)。
下面是關於棧的實現:
#include<iostream>
#include<string>
using namespace std;
template<class T>
//棧有動態與靜態之分
//棧適合用順序表(無中間插入與刪除時最好用數組),因爲棧選順序表(即是數組),進行size++與size--比較方便,而且效率較高。並且它的CPU高速緩存利用(即命中)率更高,命中,即是緩存中有,用時可以直接從緩存中取數據。
class stack
{
protected:
T* _a; //T類型的指針,指向順序表(數組)
size_t _size; //數據的個數
size_t _capacity; //棧的容量
public:
stack( const stack <T> & s)//拷貝構造函數
:_a( new T [_size]) //此處的_size也可以換成_capacity,但是最好不要,因爲這樣會浪費空間。
,_size(s._size)
, _capacity(s._size)
{
for (size_t i = 0; i < _size; ++i)
{
_a[i] = s.q[i];
}
}
//stack<T> &operator=(const stack<T> &s) //賦值運算符重載
//{
//賦值運算符重載的傳統寫法
// if (this != &s) //首先判斷是不是自己給自己賦值
// {
// //此處記住不能先釋放空間,即delete[] _a,因爲先釋放再分配空間有缺陷,因爲開闢空間可能會失敗,但是釋放空間一定會成功。
// T* tmp = new T[s._size];
// for (size_t i = 0; i < _size; ++i)
// {
// tmp[i] = s._a[i];
// }
// delete[] _a;
// _a = tmp;
// }
// return *this;
//}
stack<T > &operator=(const stack<T > &s)
{
//賦值運算符重載的現代寫法(更好)
swap(_a, s._a);
swap(_size, s._size);
swap(_capacity, s._capacity);
return *this ;
}
void Push(const T& x)
{
//檢查容量
_CheckCpapacity();
_a[_size++] = x;
}
void Pop()
{
assert(_size > 0);
--_size;
}
T& Top() //返回棧頂元素
{
assert(_size > 0);
return _a[_size - 1];
}
bool Empty()
{
return _size == 0;
}
size_t size()
{
return
}
protected:
void _CheckCapacity()
{
if (_size == _capacity)
{
_capacity = _capacity * 2 + 3;
T* tmp = new T[_capacity];
if (_a)
{
for (size_t i = 0; i < _size; ++i)
{
tmp[i] = _a[i];
}
delete[] _a;
}
_a = tmp;
}
}
};
隊列的定義
隊列值允許在表的隊尾進行插入,在表對頭進行刪除。隊列具有先進先出的特性。(FIFO,first In First Out)
下面是隊列的實現
//隊列全是動態,沒有靜態。最好用鏈式結構。
template<typename T>
struct Node
{
T _data;
Node<T > * _next;
};
template<class T>
class queue
{
protected:
Node<T > * _tail;
Node<T > * _head;
public:
queue()
:_head( NULL)
, _tail( NULL)
{}
queue( const queue <T> & q) //拷貝構造函數
:_head( NULL)
, _tail( NULL)
{
Node<T > *cur = q._head;
while (cur)
{
Push(cur->_data);
cur = cur->_next;
}
}
//queue<T> &operator=(const queue &q) //賦值運算符重載
//{
// //傳統寫法
// if (this != &q)
// {
// clear();
// Node<T> *cur = q._head;
// while (cur)
// {
// Push(cur->_data);
// cur = cur->_next;
// }
// }
// return *this;
//}
queue<T > &operator=(const queue &q ) //賦值運算符重載
{
//現代寫法
swap(_head, q._head);
swap(_tail, q._tail);
return *this ;
}
~queue()
{
Node<T > *cur = _head;
while (cur)
{
Node<T > *del = cur;
cur = cur->_next;
delete del;
}
_head = NULL;
_tail = NULL;
}
void Push(const T& x)
{
if (_head == NULL )
{
_head = _tail = new Node <T>( x);
}
else
{
_tail->_next = new Node <T>( x);
_tail = _tail->_next;
}
}
void Pop() //出隊操作,,有三種情況,分別爲隊列爲空,隊列只有一個結點,隊列有多個結點。
{
assert(_head);
if (_head == _tail) //頭指針等於尾指針,即只有一個結點。
{
delete _head;
_head = _tail = NULL;
}
else
{
Node<T > *del = _head;
_head = _head->_next;
delete del;
}
}
T& Front() //返回隊列的第一個元素
{
return _head->_data;
}
T& Back() //返回隊列的最後一個元素
{
return _tail->_data;
}
bool Empty() //判斷隊列是否爲空
{
return _head == NULL ;
}
size_t size() //返回隊列的結點的個數
{
size_t size = 0;
Node<T > *cur = _head;
while (cur)
{
++size;
cur = cur->_next;
}
return size;
}
};