栈
栈只允许在末端进行插入和删除的线性表。
栈具有后进先出的特性。
所以栈的插入删除都是在栈顶进行操作的,可以取栈顶元素(Top)
实现:用顺序表实现,由于他只能在栈顶进行操作,所以优选顺序表实现
应用:递归
图解:
栈模拟实现代码:
#include<iostream>
#include<assert.h>
using namespace std;
template<class T>
class Stack
{
public:
Stack()
:_a(NULL)
, _size(0)
, _capacity(0)
{}
void Push(const T& x)
{
CheckCapacity();
_a[_size] = x;
_size++;
}
void Pop()
{
assert(_size > 0);
--_size;
}
T& Top()
{
assert(_size > 0);
return _a[_size - 1];
}
void CheckCapacity()
{
if (_size >= _capacity)
{
_capacity = _capacity * 2 + 3;
T* tmp = new T[_capacity];
for (size_t i = 0; i < _size; ++i)
tmp[i] = _a[i];
delete[] _a;
_a = tmp;
}
}
void Print()
{
size_t i = 0;
while (i<_size)
{
cout << _a[i] << " ";
++i;
}
}
protected:
T* _a;
size_t _capacity;
size_t _size;
};
void Test()
{
Stack<int> l;
l.Push(1);
l.Push(2);
l.Push(3);
l.Push(4);
l.Print();
}
队列
队列:
允许在表的队尾进行插入,在表对头进行删除。
队列具有先进先出的特性。
所以队列的删除在队头,插入在队尾。
可以取队头数据(Front)。
应用:用于公平排队,如银行抽号系统,买火车票排队。
实现:只会在队头,队尾进行操作。所以用单链表
为什么不用双链表?
双链表太浪费,双链表的优势是在任意位置插入,而队列只能在队头或队尾操作
图解:
模拟代码实现:
#include<iostream>
using namespace std;
template<class T>
struct QueueNode
{
T _data;
QueueNode<T>* _next;
QueueNode(const T&x)
:_data(x)
, _next(NULL)
{}
};
template<class T>
class Queue
{
public:
typedef QueueNode<T> Node;
Queue()
:_head(NULL)
, _tail(NULL)
{}
void Push(const T& x)
{
if (_head ==NULL)
{
_head = _tail = new Node(x);
}
else
{
_tail->_next = new Node(x);
_tail = _tail->_next;
}
}
void Pop()
{
if (_head == NULL)
return;
else if(_head == _tail)
{
delete _head;
_head = _tail = NULL;
}
else
{
Node*del = _head;
_head = _head->_next;
delete del;
}
}
bool Emply()
{
return _head = _tail == NULL;
}
size_t Size()
{
size_t size = 0;
Node*cur = _head;
while (cur)
{
++size;
cur->cur->_next;
}
return size;
}
protected:
Node* _head;
Node* _tail;
};
void test()
{
Queue<int> q;
q.Push(1);
q.Push(2);
q.Push(3);
q.Push(4);
}
这里我们要注意的是:
template<class T>
struct QueueNode
{
T _data;
QueueNode<T>* _next;
//QueueNode(const T&x)
//:_data(x)
//, _next(NULL)
//{}
};
如果没有构造函数,程序会出现下图的错误
所以我们一定要记得写构造函数哟~