【C++】模板类链表

上一篇博客介绍了模板类顺序表,此篇博客主要是模板类链表的实现。

#pragma once
#include<iostream>
#include<string>
using namespace std;

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


template<typename T>
class LinkList
{
	template<typename T>
	friend ostream&operator<<(ostream&os, const LinkList<T>&list);
public:
	LinkList()
		:_head(NULL), _tail(NULL), _sz(0)
	{}

	~LinkList()
	{
		Release();
	}
	LinkList(const LinkList<T>&list);   //拷贝构造
	void PushBack(T x);  //尾插
	void PopBack();   //尾删
	void PushFront(T x);  //头插
	void PopFront();  //头删
	Node<T>* Find(T x);      //查找指定元素的地址
	void Insert(Node<T>* node, T x); //指定位置插入指定数据
	void Remove(T x);     //删除指定元素
	void RemoveAll(T x);  //删除链表里出现的所有指定数据
	void Erase(Node<T>* node);      //指定位置删除
	void BubbleSort();           //冒泡排序
	int& GetSz()
	{
		return _sz;
	}
public:
	void Release()
	{
		Node<T>* cur = _head;
		while (cur)
		{
			Node<T>*tmp = cur;
			cur = cur->_next;
			delete tmp;
			tmp = NULL;
		}
		_head = NULL;
		_tail = NULL;
		_sz = 0;
	}
	Node<T>*_head;
	Node<T>*_tail;
	int _sz;
};
template<typename T>
ostream&operator<<(ostream&os, const LinkList<T>&list)
{
	Node<T>*cur = list._head;
	while (cur)
	{
		os << cur->_data << "-";
		cur = cur->_next;
	}
	cout << "end" << endl;
	return os;
}

template<typename T>
LinkList<T>::LinkList(const LinkList<T>&list)
{
	Node<T>* cur = list._head;
	while (cur)
	{
		PushBack(cur->_data);
		_sz++;
		cur = cur->_next;
	}
}
template<typename T>
void LinkList<T>::PushBack(T x)
{
	Node<T>* node = new Node<T>(x);
	if (NULL == _head)
	{
		_head = node;
		_tail = node;
	}
	else
	{
		_tail->_next = node;
		node->_prev = _tail;
		_tail = node;
	}
	_sz++;
}

template<typename T>
void LinkList<T>::PopBack()   //尾删
{
	if (NULL == _head)
	{
		throw string("no data in list");
	}
	else if (NULL == _head->_next)
	{
		Release();
	}
	else
	{
		_tail = _tail->_prev;
		delete _tail->_next;
		_tail->_next = NULL;
		_sz--;
	}
}

template<typename T>
void LinkList<T>::PushFront(T x)  //头插
{
	Node<T>*NewNode = new Node<T>(x);
	if (NULL == _head)
	{
		_head = NewNode;
		_tail = NewNode;
	}
	else
	{
		NewNode->_next = _head;
		_head->_prev = NewNode;
		_head = NewNode;
	}
	_sz++;
}

template<typename T>
void LinkList<T>::PopFront()  //头删
{
	if (NULL == _head)
	{
		throw string("no data in list");
	}
	else if (NULL == _head->_next)
	{
		Release();
	}
	else
	{
		_head = _head->_next;
		delete _head->_prev;
		_head->_prev = NULL;
		_sz--;
	}
}

template<typename T>
Node<T>* LinkList<T>::Find(T x)      //查找指定元素的地址
{
	Node<T>* cur = _head;
	while (cur)
	{
		if (cur->_data == x)
		{
			return cur;
		}
		cur = cur->_next;
	}
	return NULL;
}

template<typename T>
void LinkList<T>::Insert(Node<T>* node, T x) //指定位置插入指定数据
{
	Node<T>* cur = _head;
	Node<T>* NewNode = new Node<T>(x);
	if (node == _head)
	{
		PushFront(x);
	}
	else
	{
		while (cur)
		{
			if (cur == node)
			{
				NewNode->_next = cur;
				NewNode->_prev = cur->_prev;
				cur->_prev = NewNode;
				NewNode->_prev->_next = NewNode;
				_sz++;
			}
			cur = cur->_next;
		}
	}
}

template<typename T>
void LinkList<T>::Remove(T x)     //删除指定元素
{
	Node<T>*cur = _head;
	if (_head->_data == x)
	{
		PopFront();
	}
	else
	{
		while (cur && (cur->_data != x))
		{
			cur = cur->_next;
		}
		if (cur == NULL)
		{
			cout << "no such data" << endl;
		}
		else
		{
			cur->_prev->_next = cur->_next;
			cur->_next->_prev = cur->_prev;
			cur->_next = NULL;
			cur->_prev = NULL;
			delete cur;
			_sz--;
		}
	}
}

template<typename T>
void LinkList<T>::RemoveAll(T x) //删除链表里出现的所有指定数据
{
	Node<T>*cur = _head;
	while (cur)
	{
		if ((cur->_data == x) && (cur->_next != NULL) && (cur->_prev != NULL))
		{
			Node<T> *del = cur;
			cur = cur->_next;
			del->_prev->_next = del->_next;
			del->_next->_prev = del->_prev;
			del->_next = NULL;
			del->_prev = NULL;
			delete del;
			_sz--;
		}
		else if ((cur->_data == x) && (cur->_next == NULL))
		{
			//PopBack();
			_tail = cur->_prev;
			cur->_prev = NULL;
			_tail->_next = NULL;
			delete cur;
			cur = NULL;
		}
		else if ((cur->_data == x) && (cur->_prev == NULL))
		{
			//PopFront();
			Node<T>*del = cur;
			cur = cur->_next;
			_head = _head->_next;
			_head->_prev = NULL;
			del->_next = NULL;
			delete del;
			del = NULL;
		}
		else
			cur = cur->_next;
	}
}

template<typename T>
void LinkList<T>::Erase(Node<T>* node)      //指定位置删除
{
	Node<T>* cur = _head;
	while (cur)
	{
		if ((cur == node) && (cur->_next != NULL) && (cur->_prev != NULL))
		{
			Node<T> *del = cur;
			cur = cur->_next;
			del->_prev->_next = del->_next;
			del->_next->_prev = del->_prev;
			del->_next = NULL;
			del->_prev = NULL;
			delete del;
			_sz--;
		}
		else if ((cur == node) && (cur->_next == NULL))
		{
			_tail = cur->_prev;
			cur->_prev = NULL;
			_tail->_next = NULL;
			delete cur;
			cur = NULL;
		}
		else if ((cur == node) && (cur->_prev == NULL))
		{
			//PopFront();
			Node<T>*del = cur;
			cur = cur->_next;
			_head = _head->_next;
			_head->_prev = NULL;
			del->_next = NULL;
			delete del;
			del = NULL;
		}
		else
			cur = cur->_next;
	}
}

template<typename T>
void LinkList<T>::BubbleSort()           //冒泡排序
{
	Node<T>* cur = _head;
	Node<T>* EndOk = NULL;
	while (cur->_next)
	{
		Node<T>*incur = _head;
		while (incur->_next != EndOk)
		{
			if (incur->_data > incur->_next->_data)
			{
				T tmp = incur->_data;
				incur->_data = incur->_next->_data;
				incur->_next->_data = tmp;
			}
			incur = incur->_next;
		}
		EndOk = incur;
		cur = cur->_next;
	}
}


void test1()
{
	LinkList<int>list;
	list.PushBack(1);
	list.PushBack(2);
	list.PushBack(3);
	list.PushBack(4);
	//LinkList<int>list1(list);
	cout << list << endl;
	list.PopBack();
	cout << list << endl;
	list.PopBack();
	cout << list << endl;
	list.PopBack();
	cout << list << endl;
	try
	{
		list.PopBack();
	}
	catch (string e)
	{
		cout << e << endl;
	}
	cout << list << endl;
	try
	{
		list.PopBack();
	}
	catch (string e)
	{
		cout << e << endl;
	}
	cout << list << endl;
}

void test2()
{
	LinkList<int> list;
	list.PushFront(1);
	list.PushFront(2);
	list.PushFront(3);
	cout << list << endl;
	try{ list.PopFront(); }
	catch (string e)
	{
		cout << e << endl;
	}
	cout << list << endl;
	try{ list.PopFront(); }
	catch (string e)
	{
		cout << e << endl;
	}
	cout << list << endl;
	try{ list.PopFront(); }
	catch (string e)
	{
		cout << e << endl;
	}
	cout << list << endl;
	try{ list.PopFront(); }
	catch (string e)
	{
		cout << e << endl;
	}
	cout << list << endl;
}

void test3()
{
	LinkList<int> list;
	list.PushBack(1);
	list.PushBack(2);
	list.PushBack(3);
	cout << list << endl;
	Node<int>* ret = list.Find(3);
	list.Insert(ret, 9);
	cout << list << endl;
	LinkList<string> list1;
	list1.PushBack("ajffas");
	list1.PushBack("adgadgagasdjga");
	cout << list1 << endl;
	LinkList<string> list2(list1);
	cout << list2 << endl;
}

void test4()
{
	LinkList<int> list;
	list.PushBack(2);
	list.PushBack(1);
	list.PushBack(2);
	list.PushBack(3);
	list.PushBack(2);
	list.PushBack(2);
	cout << list << endl;
	/*list.Remove(2);
	cout << list << endl;*/
	list.RemoveAll(2);
	cout << list << endl;
}

void test5()
{
	LinkList<int> list;
	list.PushBack(1);
	list.PushBack(2);
	list.PushBack(3);
	list.PushBack(4);
	cout << list << endl;
	/*Node<int>*ret = list.Find(2);
	list.Erase(ret);*/
	cout << list << endl;
}

void test6()
{
	LinkList<int> list;
	list.PushFront(1);
	list.PushFront(2);
	list.PushFront(3);
	list.PushFront(4);
	cout << list << endl;
	list.BubbleSort();
	cout << list << endl;
}
     当然,模板也有利弊,虽然它复用了代码,节省资源,可以更快的迭代开发,增强了代码的灵活性。但是模板让代码变得错综复杂,不易维护,编译代码时间变长。而且,当出现错误时,错误信息非常凌乱,亲自感受一下就能知道,每次发生一个错误,真的要好久才能找到错在哪里,不易定位错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值