栈的定义

  是一种只能在一端进行插入或删除操作的线性表。

   表中允许进行插入、删除操作的一端称为栈顶。栈顶的当前位置是动态的,由栈顶指针来指示。表的另一端称为栈底。当栈中没有数据元素时,称为空栈。栈的插入操作通常称为进栈或入栈,栈的删除操作通常称为退栈或出栈

   栈的特殊性在于限定插入和删除数据元素的操作只能在线性表的一端进行,所以栈的特点后进先出Last In First Out),栈简称为LIFO线性表。

wKiom1cWQWSiIYBRAABOCEz1WE0075.jpg

Stack.h

#pragma once

template <class T>
class Stack
{

public:
	Stack()        //构造函数
		:_arr(NULL)
		, _top(0)
		, _capacity(0)
	{}
	~Stack()          //析构函数
	{
		if (_arr)
		{
			delete[] _arr;
		}
	}
public:
	void Push(const T& x)         //插入
	{
		_CheckCapacity();
		_arr[_top++] = x;
	}
	void Pop()          //删除
	{
		assert(_top > 0);
		--_top;
	}
	size_t Size()         //大小
	{
		return _top;
	}
	bool Empty()         //判断栈是否为空
	{
		//return _top == 0;
		if (_top <= 0)
		{
			return true;
		}
		else
			return false;
	}
	T& Top()        //获取栈顶元素
	{
		return _arr[_top - 1];
	}

protected:
	void _CheckCapacity()
	{
		if (_arr == NULL)
		{
			_capacity = 5;
			_arr = new T[_capacity];
			return;
		}
		else if (_top == _capacity)
		{
			_capacity *= 2;
			T* tmp = new T[_capacity];
			for (size_t i = 0;i < _top;++i)
			{
				tmp[i] = _arr[i];
			}
			delete[] _arr;
			_arr = tmp;
		}
	}
protected:
	T* _arr;
	size_t _top;
	size_t _capacity;
};

void TestStack()     //测试用例
{
	Stack<char> s;
	s.Push('a');
	s.Push('b');
	s.Push('c');
	s.Push('d');

	while (!s.Empty())
	{
		cout << s.Top() << " ";
		s.Pop();
	}
	cout << endl;
}


队列的定义

  队列简称队,它也是一种运算受限的线性表,其限制仅允许在表的一端进行插入,而在表的另一端进行删除。

   把进行插入操作的一端称为队尾(rear),进行删除操作的一端称为队首或队头(front)。

   向队列中插入新元素称为进队或入队,新元素入队后就成为新的队尾元素;从队列 中删除元素称为出队或离队,元素出队后,其后继元素就成为队首元素。

   队的特殊性在于插入只能在表的一端进行(只进不出),而删除只能在表的另一端进行(只出不进),所以队列的操作原则是先进先出,又称作FIFO表(First In First Out)。

wKioL1cWRdKh1pLzAAA_O__jOD4871.jpg

Queue.h

#pragma once

template <class T>
struct Node
{
	T _data;
	Node<T>* _next;
	Node(const T& x)
		:_data(x)
		,_next(NULL)
	{}
};

template <class T>
class Queue
{
public:
	Queue()
		:_head(NULL)
		,_tail(NULL)
		,_size(0)
	{}

	~Queue()
	{
		if (_head)
		{
			delete _head;
		}
	}
public:
	void Push(const T& x)      //在队尾插入数据
	{
		if (_head == NULL)       //队列为空的情况
		{
			_head = _tail = new Node<T>(x);
		}
		else
		{
			_tail->_next = new Node<T>(x);
			_tail = _tail->_next;
		}
		++_size;
	}

	void Pop()      //在队头删除数据
	{
		assert(_head);
		if (_head == _tail)     //队列只有一个数据的情况
		{
			delete _head;
			_head = _tail = NULL;
		}
		else
		{
			Node<T>* tmp = _head;
			_head = _head->_next;
			delete tmp;
		}
		--_size;
	}

	bool Empty()
	{
		return _head == NULL;
	}

	size_t Size()
	{
		return _size;
	}

	T& GetFront()      //获取队头数据
	{
		assert(_head);
		return _head->_data;
	}

	T& GetTail()      //获取队尾数据
	{
		assert(_tail);
		return _tail->_data;
	}

protected:
	Node<T>* _head;
	Node<T>* _tail;
	size_t _size;
};

void TestQueue()      //测试用例
{
	Queue<int> q;
	q.Push(1);
	q.Push(2);
	q.Push(3);
	q.Push(4);

	while (!q.Empty())
	{
		cout << q.GetFront() << " ";
		q.Pop();
	}
	cout << endl;
}