下面介绍模板类来实现双链表表和队列,由于队列是先进先出原则,所以可以通过调用双链表实现进队和出队等操作,Container<T>为“容器”,利用模板的模板参数--容器适配器调用双链表。

下面用模板实现了顺序表的头插、尾插、头删、尾删、逆置、排序、去重、合并两个链表及增删查改等操作。

如下所示:

#pragma once

#include<string>
#include<assert.h>

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

template<class T>
class List
{
public:
	List()
		:_head(NULL)
		, _tail(NULL)
	{}
	List(const List<T>& s)
		:_head(NULL)
		, _tail(NULL)
	{
		ListNode<T>* cur = s._head;
		while (cur)
		{
			this->PushBack(cur->_data);
			cur = cur->_next;
		}
	}
	List<T>& operator=(List<T>& s)
	{
		ListNode<T>* cur = s._head;
		while (cur)
		{
			this->PushBack(cur->_data);
			cur = cur->_next;
		}
		swap(_head, s._head);
		swap(_tail, s._tail);
		return *this;
	}
	~List()
	{
		ClearList();
	}
public:
	void PrintList()//打印双链表
	{
		ListNode<T>* cur = _head;
		while (cur)
		{
			cout << cur->_data << "->";
			cur = cur->_next;
		}
		cout << "NULL" << endl;
	}
	void ClearList()//释放所有节点
	{
		ListNode<T>* tmp = _head;
		while (tmp)
		{
			ListNode<T>*del = tmp;
			tmp = tmp->_next;
			delete del;
			del = NULL;
		}
	}
	void PushBack(const T& x)//尾插
	{
		if (_head == NULL)
		{
			_head = _tail = new ListNode<T>(x);
		}
		else
		{
			ListNode<T>* next = new ListNode<T>(x);
			_tail->_next = next;
			next->_prev = _tail;
			_tail = next;
			_tail->_next = NULL;
		}
	}
	void PopBack()//尾删
	{
		if (_head == _tail)
		{
			if (_head)
			{
				delete _tail;
				_head = _tail = NULL;
			}
		}
		else
		{
			ListNode<T>* prev = _tail->_prev;
			delete _tail;
			prev->_next = NULL;
			_tail = prev;
		}
	}
	void PushFront(const T& x)//头插
	{
		if (_head == NULL)
		{
			_head = _tail = new ListNode<T>(x);
		}
		else
		{
			ListNode<T>* cur = new ListNode<T>(x);
			cur->_next = _head;
			_head->_prev = cur;
			_head = cur;
		}
	}
	void PopFront()//头删
	{
		if (_head == _tail)
		{
			if (_head)
			{
				delete _head;
				_head = _tail = NULL;
			}
		}
		else 
		{
			ListNode<T>* cur = _head->_next;
			delete _head;
			_head = cur;
			cur->_prev = NULL;
		}
	}
	ListNode<T>* Find(const T& x)//查找x位置
	{
		ListNode<T>* cur = _head;
		while (cur)
		{
			if (x == cur->_data)
			{
				return cur;
			}
			cur = cur->_next;
		}
		return NULL;
	}
	void Insert(ListNode<T>* pos,const T& x)//在pos位置处添加x
	{//注意考虑pos==_head时
		assert(pos);
		if (pos == _head)
		{
			PushFront(x);
		}
		else
		{
			ListNode<T>* prev = pos->_prev;
			ListNode<T>* cur = new ListNode<T>(x);
			ListNode<T>* next = pos;
			prev->_next = cur;
			cur->_prev = prev;
			cur->_next = next;
			next->_prev = cur;
		}
	}
	void Erase(ListNode<T>* pos)//删除节点
	{//注意考虑pos==_head,pos==_tail时
		assert(pos);
		if (pos == _head)
		{
			PopFront();
		}
		else if(pos == _tail)
		{
			PopBack();
		}
		else
		{
			ListNode<T>* prev = pos->_prev;
			ListNode<T>* next = pos->_next;
			delete pos;
			prev->_next = next;
			next->_prev = prev;
		}
	}
	void Reverse()//逆置
	{
		swap(_head, _tail);
		ListNode<T>* cur = _head;
		while (cur)
		{
			swap(cur->_prev, cur->_next);
			cur = cur->_next;
		}
	}
	void Sort()//冒泡排序
	{
		ListNode<T>* tmp = NULL;
		while (tmp != _head->_next)
		{
			ListNode<T>* cur = _head;
			ListNode<T>* next = cur->_next;
			while (tmp != next)
			{
				if (cur->_data > next->_data)
				{
					swap(cur->_data, next->_data);
				}
				cur = cur->_next;
				next = next->_next;
			}
			tmp = cur;//tmp指向cur,即比较到某值处
		}
	}
	void Unique()//去重,针对有序链表
	{
		ListNode<T>* cur = _head;
		ListNode<T>* next = _head->_next;
		while (next)
		{
			while (cur->_data == next->_data)
			{
				ListNode<T>* tmp = next;
				next = next->_next;
				Erase(tmp);
			}
			cur = cur->_next;
			next = next->_next;
		}
	}
	void Merge(List<T>& l)//合并,相当将链表l追加在原链表后面
	{
		_tail->_next = l._head;
		l._head->_prev = _tail;
	}
	void Splice(ListNode<T>* pos, List<T>& l)//某一链表插入到pos后面
	{
		assert(pos);
		if (pos == _tail)
		{
			Merge(l);
		}
		else
		{
			ListNode<T>* cur = pos;
			ListNode<T>* next = pos->_next;
			cur->_next = l._head;
			l._head->_prev = cur;
			next->_prev = l._tail;
			l._tail->_next = next;
			_tail->_next = NULL;
		}
	}
	size_t Size()//双链表的长度
	{
		ListNode<T>* cur = _head;
		size_t size = 0;
		while (cur)
		{
			size++;
			cur = cur->_next;
		}
		return size;
	}
public:
	ListNode<T>* _head;
	ListNode<T>* _tail;
};

   queue是容器配接器C的一个示例,容器配接器C将一些基础容器转换成类C的容器。容器配接器queue、stack、priority_queue——与标准模板库的其他处理是截然不同的。他们的方法和定义要调用基础容器类的方法。queue的基础类可以为list,list类中有size,empty,push_back,pop_front,front,back方法。deque类也可以作为基础类,而且是默认的基础类。vector类不能作为基础类,vector类没有pop_front方法。

函数列表:

empty() 如果队列空则返回真 

front() 返回第一个元素 

pop() 删除第一个元素 

push() 在末尾加入一个元素 

size() 返回队列中元素的个数

队列的实现入队、出队、判空、队头、队尾及队中元素个数等操作

template<class T,template<class>class Container=List>
class Queue
{
public:
	bool Empty()//判空
	{
		return _con.Size() == 0;
	}
	size_t Size()//求队列大小
	{
		return _con.Size();
	}
	T& Front()//求出队头元素
	{
		assert(_con._head);
		return _con._head->_data;
	}
	T& Back()//求出队尾元素
	{
		assert(_con._tail);
		return _con._tail->_data;
	}
	void PushBack(const T& x)//入队
	{
		_con.PushBack(x);
	}
	void PopFront()//出队
	{
		_con.PopFront();
	}
	void PrintQueue()
	{
		_con.PrintList();
	}
protected:
	Container<T> _con;
};

双链表及队列的测试用例如下:

void Test1()
{//尾插尾删
	//List<int> s1;
	//s1.PushBack(1);
	//s1.PushBack(2);
	//s1.PushBack(3);
	//s1.PrintList();
	List<string> s2;
	s2.PushBack("xxxxxx");
	s2.PushBack("yyyyyy");
	s2.PushBack("zzzzzz");
	s2.PrintList();

	List<string> s4(s2);
	s4.PrintList();
	List<string> s3;
	s3 = s2;
	s3.PrintList();
	//s2.PopBack();
	//s2.PopBack();
	//s2.PrintList();
	//s2.PopBack();
	//s2.PopBack();
	//s2.PrintList();
}

void Test2()
{//头插头删
	List<int> s1;
	s1.PushFront(1);
	s1.PushFront(2);
	s1.PushFront(3);
	s1.PrintList();
	List<string> s2;
	s2.PushFront("xxxxxx");
	s2.PushFront("yyyyyy");
	s2.PushFront("zzzzzz");
	s2.PrintList();
	s2.PopFront();
	s2.PopFront();
	s2.PrintList();
	s2.PopFront();
	s2.PopFront();
	s2.PrintList();
}

void Test3()
{//查找,增加,删除,逆置
	List<string> s;
	s.PushBack("xxxxxx");
	s.PushBack("yyyyyy");
	s.PushBack("zzzzzz");
	s.PrintList();
	s.Insert(s.Find("xxxxxx"), "ffffff");
	s.PrintList();
	s.Erase(s.Find("ffffff"));
	s.PrintList();
	s.Reverse();
	s.PrintList();
}

void Test4()
{//冒泡排序,去重
	List<string> s1;
	s1.PushBack("yyyyyy");
	s1.PushBack("zzzzzz");
	s1.PushBack("xxxxxx");
	List<string> s2;
	s2.PushBack("qqqqqq");
	s2.PushBack("ffffff");
	s2.PushBack("ssssss");
	s1.PrintList();
	s2.PrintList();
	s1.Sort();
	s2.Sort();
	s1.PrintList();
	s2.PrintList();
	List<string> s3;
	s3.PushBack("yyyyyy");
	s3.PushBack("qqqqqq");
	s3.PushBack("zzzzzz");
	s3.PushBack("xxxxxx");
	s3.PushBack("qqqqqq");
	s3.PushBack("xxxxxx");
	s3.PushBack("xxxxxx");
	s3.PushBack("ssssss");
	s3.Sort();
	s3.PrintList();
	s3.Unique();
	s3.PrintList();
}

void Test5()
{//合并链表,某一链表插入到pos后面
	List<string> s1;
	s1.PushBack("xxxxxx");
	s1.PushBack("rrrrrr");
	s1.PushBack("pppppp");
	s1.PushBack("qqqqqq");
	List<string> s2;
	s2.PushBack("wwwwww");
	s2.PushBack("vvvvvv");
	s2.PushBack("uuuuuu");
	s1.Sort();
	s1.PrintList();
	s2.Sort();
	s2.PrintList();
	//s1.Merge(s2);
	//s1.PrintList();
	//s1.Sort();
	//s1.PrintList();
	//s2._head->_prev = NULL;
	//s1._tail->_next = NULL;
	ListNode<string>* pos = s1.Find("rrrrrr");
	s1.Splice(pos, s2);
	s1.PrintList();
	pos->_prev = NULL;
	pos->_next = NULL;
	s2._head->_prev = NULL;
	s2._tail->_next = NULL;
}
void Test6()
{
	//Queue<int> s1;
	//s1.PushBack(1);
	//s1.PushBack(2);
	//s1.PushBack(3);
	//cout << s1.Empty() << endl;
	//cout << "Front->" << s1.Front() << endl;
	//cout << "Back->" << s1.Back() << endl;
	s1.PopFront();
	s1.PrintQueue();
	s1.PopFront();
	s1.PopFront();
	s1.PopFront();
	s1.PrintQueue();

	Queue<string> s2;
	s2.PushBack("ssssss");
	s2.PushBack("xxxxxx");
	s2.PushBack("yyyyyy");
	s2.PushBack("zzzzzz");
	cout << s2.Empty() << endl;
	cout << "Size->" << s2.Size() << endl;
	cout << "Front->" << s2.Front() << endl;
	cout << "Back->" << s2.Back() << endl;
	string out = s2.Front();
	//访问队列
	while (!s2.Empty())
	{
		cout << s2.Front() << "->";
		s2.PopFront();
	}
	cout << "NULL" << endl;
}