带头尾节点的双向循环链表

注意测试用例的选取!!

#include<iostream>
using namespace std;
#include<string>
template<class T>
struct LinkNode
{
	LinkNode(const T& x)
	:_data(x)
	, _prev(NULL)
	, _next(NULL)
	{

	}
	T _data;
	LinkNode<T>* _prev;
	LinkNode<T>* _next;
};
template<class T>
class List
{
public:
	List()
	:_head(NULL)
	, _tail(NULL)
	{}
	List(const List<T>& l)
	:_head(NULL)
	, _tail(NULL)
	{
		LinkNode<T>* cur = l._head;
		if (cur == NULL)
		{
			return;
		}
		(*this).PushBack(cur->_data);
		while (cur&&cur->_next!=l._head)
		{
			cur = cur->_next;
			(*this).PushBack(cur->_data);
		}
	}
	List<T>& operator=(List<T> l)
	{
		swap(_head, l._head);
		swap(_tail, l._tail);
	}
	void PushBack(const T& x)
	{
		if (_head == NULL)
		{
			_head = new LinkNode<T>(x);
			_tail= _head;
		}
		else
		{
			LinkNode<T>* tmp = new LinkNode<T>(x);
			_tail->_next = tmp;
			tmp->_prev = _tail;
			_tail = _tail->_next;
			_tail->_next = _head;
			_head->_prev = _tail;
		}
	}
	void PopBack()
	{
		Destory();
	}
	void Print()
	{
		LinkNode<T>* cur = _head;
		if (cur == NULL)
		{
			return;
		}
		cout << (cur->_data) << "->";
		while (cur&&cur->_next!= _head)
		{
			cur = cur->_next;
			cout << (cur->_data) << "->";
		}
		cout<<"NULL" << endl;
	}
	~List()
	{
		while (_head!=NULL)
		{
           Destory();
		}
	}
	LinkNode<T>* Find(const T& x)
	{
		LinkNode<T>* cur = _head;
		if (cur == NULL)
		{
			return NULL;
		}
		if (cur->_data == x)
		{
			return cur;
		}
		while (cur->_next != _head)
		{
			cur = cur->_next;
			if (cur->_data == x)
				return cur;
		}
		return NULL;
	}
	void Insert(LinkNode<T>* pos, const T& x)
	{
		if(pos==NULL)
			return;
		LinkNode<T>* tmp = new LinkNode<T>(x);
		tmp->_prev = pos;
		tmp->_next = pos->_next;
		pos->_next = tmp;
	}
	void Erase(LinkNode<T>* pos)
	{
		if (pos == NULL)
			return;
		else if (pos == _tail)
		{
			_tail = _tail->_prev;
		}
		else if (pos == _head)
		{
			_head = _head->_next;
		}
		LinkNode<T>* del = pos;
		LinkNode <T>* next = pos->_next;
		LinkNode<T>* prev = pos->_prev;
		if(prev)
			prev->_next = next;
		if(next)
			next->_prev =prev;
		delete del;
	}
protected:
	void Destory()
	{
		if (_head == NULL)
		{
			return;
		}
		else if(_head == _tail)
		{
			delete _head;
			_head = _tail = NULL;
		}
		else
		{
			LinkNode<T>* del = _head;
			_head = _head->_next;
			_head->_prev = del->_prev;
			del->_prev->_next = _head;
			delete del;
		}
	}
protected:
	LinkNode<T>* _head;
	LinkNode<T>* _tail;
};
void Test1()
{
	List<int> l;
	l.PushBack(1);
	l.PushBack(2);
	l.PushBack(3);
	l.PushBack(4);
	l.PushBack(5);
	l.Print();
	List<int> l1(l);
	l1.Print();
}
void Test2()
{
	List<int> l;
	l.PushBack(1);
	l.PushBack(2);
	l.PushBack(3);
	l.PushBack(4);
	l.PushBack(5);
	l.Print();
	List<int> l1(l);
	l1.Print();
	List<int> l2;
	l2.PushBack(6);
	l2.PushBack(7);
	l2.PushBack(8);
	l2.PushBack(9);
	l2.PushBack(10);
	l2.Print();
}
void Test3()
{
	List<string> l1;
	l1.PushBack("abc");
	l1.PushBack("edf");
	l1.PushBack("th");
	l1.PushBack("ik");
	l1.Print();
	List<string> l2(l1);
	l2.Print();
	l2.PopBack();
	l2.PopBack();
	l2.Print();
	l2.PopBack();
	l2.PopBack();
	l2.PopBack();
	l2.PopBack();
	l2.PopBack();
	l2.Print();
}
void Test4()
{
	List<int> l;
	l.PushBack(1);
	l.PushBack(2);
	l.PushBack(3);
	l.PushBack(4);
	l.PushBack(5);
	l.Insert(l.Find(2), 8);
	l.Print();
	l.Erase(l.Find(1));
	l.Print();
}
void Test5()
{
	List<string> l;
	l.PushBack("abc");
	l.PushBack("def");
	l.Erase(l.Find("abc"));
	l.Print();
}
int main()
{
	Test5();
	system("pause");
	return 0;
}
时间: 2024-10-14 14:58:07

带头尾节点的双向循环链表的相关文章

带头尾节点的双向链表

#include<iostream> #include<assert.h> using namespace std; typedef int DataType; //双向链表,无头节点 struct LinkNode { //struct默认是公有访问限定符 public: LinkNode(const DataType& x) :_data(x) , _prev(NULL) , _next(NULL) {} ~LinkNode() { } public: DataType

复习下C 链表操作(双向循环链表,查找循环节点)

双向循环链表  和 单向循环链表 查找循环节点 思路都是一样. 快慢指针查找法. 理论可参考 c 链表之 快慢指针 查找循环节点 typedef struct Student_Double { char name[10]; int point; struct Student_Double *preStu; struct Student_Double *nextStu; } StudentDouble; StudentDouble * CreateDoubleCircleLink_Table(){

C语言双向循环链表实现及图示(初始化/插入链表/清空/销毁)

-------------------------------------------- 双向循环链表 //遍历等执行方法与普通双向链表相同,不单独列举 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 初始化+尾插法 图示: 实现代码 1 /* 初始化

算法导论之九(10.2不带哨兵节点和带哨兵节点的双向链表)

不带哨兵节点的双向链表即一般的双向链表,有一个头指针指向第一个节点,每个节点有key值和两个指针next和pre,分别指向前后相邻的节点,头结点的pre=NULL,尾节点的next=NULL,比较明了,但是也有麻烦的地方:在做查找删除节点等操作的时候,免不了要判断边界条件,比如node==NULL等.先来看看这种链表的代码: /* * 实现没有哨兵节点的双向链表,需要自己判断边界条件 */ #include <iostream> using namespace std; class list

C语言通用双向循环链表操作函数集

说明 相比Linux内核链表宿主结构可有多个链表结构的优点,本函数集侧重封装性和易用性,而灵活性和效率有所降低.     可基于该函数集方便地构造栈或队列集.     本函数集暂未考虑并发保护. 一  概念 链表是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序通过链表中的指针链接次序实现.链表由一系列存储结点组成,结点可在运行时动态生成.每个结点均由两部分组成,即存储数据元素的数据域和存储相邻结点地址的指针域.当进行插入或删除操作时,链表只需修改相关结点的指针域即可,因此相比线性

双向循环链表 初始化 插入 删除

#include <stdio.h> #include <stdlib.h> #define OK 1 #define ERROR -1 #define TRUE 1 #define FALSE -1 #define NULL 0 #define OVERFLOW -2 #define ElemType int #define Status int typedef int ElemType typedef int Status #define LEN sizeof(DuLNode)

双向循环链表

//双向循环链表 typedef int datatype; //方便修改 //当然也可以写成模板来适应更多的数据类型 struct dclink{ datatype data;//数据定义 struct dclink *pre; struct dclink *next;//前驱和后继指针 }; class DCLink { public: DCLink();//default constructor DCLink(datatype data);//单参constructor void add(

算法导论13:双向循环链表 2016.1.13

今天这个又打了很长时间,本来觉得数据结构就是那样,不过是一种思维,但是实际上真正自己打和想象中差距还是很大,需要考虑到各种细节. 今天这个问题有一个比较有意思的应用,就是“约瑟夫环问题”. 具体可以参见百度百科: http://baike.baidu.com/link?url=poA1Aanlptc6yzP1puYhSw_0RQjRAplhPfHwk6eoiqMNxw6WigCEbexxZ8a9SUbrMGokpPbKNzVYw308xjeEw_ 读完问题就可以发现,这个问题用链表就是一个很完美

c语言编程之双向循环链表

双向循环链表就是形成两个环,注意每个环的首尾相连基本就可以了. 程序中采用尾插法进行添加节点. 1 #include<stdio.h> 2 #include<stdlib.h> 3 #define element int 4 typedef struct Node{ 5 element data; 6 struct Node *next; 7 struct Node *prior; 8 }*pNode; 9 10 //build a new double loop list 11