模板实现双向循环链表

List.h

#pragma once
#include<iostream>
using namespace std;
#include<assert.h>
//template <class T>
//struct ListNode
//{
//
//	T _data;
//	 ListNode<T> *_prev;//注意ListNode<T>是类型   ListNode是类名
//	 ListNode<T> *_next;
//};
//template <class T>
//class List
//{   
//private:
//	ListNode <T>_head;
//
//};
template <class T>
struct ListNode
{

	T _data;
	ListNode<T> *_prev;//注意ListNode<T>是类型   ListNode是类名
	ListNode<T> *_next;

	ListNode (const T& x)
		:_data(x)
		, _next(NULL)
		, _prev(NULL)
	{}
};
template <class T>
class List
{
	typedef ListNode<T>  Node;
public:
	List()
		:_head(new Node(T()))//此处不能传空,如果类型是int可以传空,但是如果是string会出问题  无参构造函数,构造匿名对象
	{ 
	  _head->_prev = _head;
	  _head->_next = _head;
	}
	
	List(const List<T> &l)  
		:_head(new Node(T()))//初始化头  本句和底下两句即为初始化头
	{
		_head->_next = _head;
		_head->_prev = _head;
		Node * cur = l._head->_next;
		while (cur != l._head)
		{
			PushBack(cur->_data);
			cur = cur->_next;
		}	
	}
	List<T> &operator=( List<T> l)
	{
		if (this != &l)
		{
			swap(_head, l._head);
		}
		return *this;
	}
	/*List<T> &operator=(const List<T>& l)
	{
		if (this != &l)
		{

			List<T> tmp(l);
			swap(tmp._head, _head);
		}
		return *this;
	}*/
	~List()
	{
		Clear();
		delete _head;
		_head = NULL;
	}
	void PushBack(const T& x)
	{
		Node* tail = _head->_prev;
		Node* newNode = new Node(x);
		newNode->_next = _head;
		_head->_prev = newNode;
		tail->_next = newNode;
		newNode->_prev = tail;
	}
	void PopBack()
	{  //要保证链表非空,不能把头结点干掉
		assert(!Empty());
		Node *tail = _head->_prev;
		Node *prev = tail->_prev;
		delete tail;
		prev->_next = _head;
		_head->_prev = prev;

	}
	void PushFront(const T&x)
	{
		Node *next = _head->_next;
		Node * newNode = new Node(x);
		next->_prev = newNode;
		newNode->_next = next;
		_head->_next = newNode;
		newNode->_prev = _head;
	}
	void PopFront()
	{//要保证非空 不能把头干掉
		assert(!Empty());
		Node * pos = _head->_next;
		Node * next = pos->_next;
		delete pos;
		_head->_next = next;
		next->_prev = _head;

	}
	Node *Find(const T& x)
	{
		Node *cur = _head->_next;
		while (cur != _head)
		{
			if (cur->_data == x)
			{
				return cur;
			}
			cur = cur->_next;
		}
		return NULL;
	}
	void Insert(Node *pos, const T&x)//在pos结点前插入一个结点     注意的是必须先把prev与新增结点连接,再把pos与新增结点连接   顺序不能换
	{
		assert(pos);
		Node *prev = pos->_prev;
		Node *newNode = new Node(x);
		prev->_next = newNode;
		newNode->_prev = prev;
		newNode->_next = pos;
		pos->_prev = newNode;

	}
	void Erase(Node *pos)
	{
		assert((pos) && (pos != _head));
		Node *prev = pos->_prev;
		Node *next = pos->_next;
		prev->_next = next;
		next->_prev = prev;
		delete pos;

	}
	void Clear()//清除不清除头,析构才清理头
	{
		Node * cur = _head->_next;
		while (cur != _head)
		{
			Node*next = cur->_next;
			delete cur;
			cur = next;
		}
		_head->_prev = _head;//此时要把它恢复到开始哨兵位的状态,不然为野指针
		_head->_next = _head;

	}
	bool Empty()
	{
		return (_head->_next == _head);
	}
	void print()
	{
		Node *cur = _head->_next;
		while (cur != _head)
		{
			cout << cur->_data << " ";
			cur = cur->_next;
		}
		cout << endl;
	}
private:
	Node* _head; //(哨兵位)

};

test.c

#include"List.h"

void TestList1()//测试PushBack  PopBack  Print
{
	List<int>l1;
	l1.PushBack(1);
	l1.PushBack(2);
	l1.PushBack(3);
	l1.PushBack(4);
	l1.print();
	l1.PopBack();
	l1.PopBack();
	l1.PopBack();
	l1.print();
	l1.PopBack();
	l1.print();

}
void TestList2()//测试PopFront PushFront
{
	List<int>l2;
	l2.PushFront(1);
	l2.PushFront(2);
	l2.PushFront(3);
	l2.PushFront(4);
	l2.print();
	l2.PopFront();
	l2.PopFront();
	l2.PopFront();
	l2.print();
	l2.PopFront();
	l2.print();
}
void TestList3()
{
	List<int>l3;
	l3.PushBack(1);
	l3.PushBack(2);
	l3.PushBack(3);
	l3.PushBack(4);
	l3.print();
	l3.Insert(l3.Find(1), 0);
	l3.print();
	List <int>l4(l3);//测拷贝构造
	l4.print();
	List<int>l2;
	l2.PushBack(1);
	l4 = l2;//测赋值运算符重载
	l4.print();

	
}
int main()
{
	//TestSeqList();
	//TestList1();
	//TestList2();
	TestList3();
	system("pause");
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值