数据结构之双向循环链表

本文主要讲述含有只含有头结点的双向循环链表,其中头文件C.h和线性表抽象类AList.h文件见:http://blog.youkuaiyun.com/yongjiankuang/article/details/71330628

//双向循环链表结点定义;
#ifndef _DLNode_H_
#define _DLNode_H_

template<typename T> struct DLNode
{
	T data;
	DLNode<T> *prior;//前驱;
	DLNode<T> *next;//后继;
};

#endif;


//双向循环链表类的定义;
#ifndef _DLINKLIST_H_
#define _DLINKLIST_H_

#include "C.h"
#include "AList.h"
#include "DLNode.h"

template<typename T> class DLinkList :public AList < T >
{
private:
	DLNode<T> *Head;//头指针;

	DLNode<T>* GetElemP(int i) const//获取第i个元素的指针;
	{
		int j = 0;
		DLNode<T> *p = Head;//p指向头结点;

		//如果输入i非法;
		if (i < 0)
			return NULL;
		//如果i为0,则返回头结点;
		if (i == 0)
			return p;
		//其他情形下;
		do
		{
			j++;
			p = p->next;
		} while (p != Head && j < i);

		if (p == Head)
			return NULL;
		else
			return p;
	}

	//寻找链表中与e相等元素的地址;
	DLNode<T>* GetElemE(T e, bool(*eq)(T, T)) const
	{
		DLNode<T> *p = Head->next;//p指向第一个结点;
		while (p != Head)
		{
			if (eq(p->data, e))
				return p;
			p = p->next;
		}
		return NULL;
	}

public:
	//构造函数创建空的双向链表;
	DLinkList()
	{
		Head = new DLNode < T > ;
		assert(Head != NULL);
		Head->next = Head->prior = Head;//头结点的指针域指向自身;
	}

	//析构函数,销毁链表;
	~DLinkList()
	{
		ClearList();
		delete Head;
	}

	//置链表为空;
	void ClearList() const
	{
		DLNode<T> *p;
		p = Head->next;
		while (p != Head)
		{
			p = p->next;
			delete p->prior;
		}

		Head->next = Head->prior = Head;//头结点的两个指针均指向自身;
	}

	bool ListEmpty() const
	{
		return Head->next == Head;
	}

	//获取链表的长度;
	int ListLength() const
	{
		int i = 0;
		DLNode<T> *p;
		p = Head->next;
		while (p != Head)
		{
			i++;
			p = p->next;
		}

		return i;
	}

	//获取链表中第i个元素的值
	bool GetElem(int i, T &e) const
	{
		DLNode<T> *p;
		p = GetElemP(i);
		if (p != NULL)
		{
			e = p->data;
			return true;
		}
		return false;
	}

	//返回与e相等的元素的位序;
	int LocateElem(T e, bool(*eq)(T, T)) const
	{
		int i = 0;
		DLNode<T> *p;
		p = Head->next;
		while (p != Head)
		{
			i++;
			if (eq(e, p->data))
				return i;
			p = p->next;
		}

		return 0;
	}

	//获取与e相等的元素的前一个元素;
	bool PriorElem(T e, bool(*eq)(T, T), T &pre_e) const
	{
		DLNode<T> *p;
		p = GetElemE(e,eq);
		if (p != NULL && p -> prior != Head)
		{
			pre_e = p->prior->data;
			return true;
		}
		return false;
	}

	//获取与e相等的元素的下一个元素;
	bool NextElem(T e, bool(*eq)(T, T), T &next_e) const
	{
		DLNode<T> *p;
		p = GetElemE(e, eq);
		if (p != NULL && p->next != Head)
		{
			next_e = p->next->data;
			return true;
		}
		return false;
	}


	//向双链表中插入元素;
	bool ListInsert(int i, T e)
	{
		DLNode<T> *p, *s;
		p = GetElemP(i - 1);
		if (p == NULL)
			return false;
		s = new DLNode < T > ;
		if (s == NULL)
			return false;
		s->data = e;
		s->prior = p;
		s->next = p->next;
		p->next->prior = s;
		p->next = s;
		return true;
	}

	//删除双链表的第i个元素;
	bool ListDelete(int i, T &e) const
	{
		DLNode<T> *p;
		p = GetElemP(i);
		if (p == NULL)
			return false;
		e = p->data;
		p->prior->next = p->next;
		p->next->prior = p->prior;
		delete p;
		return true;
	}



	//双链表遍历输出;
	void ListTraverse(void(*v)(T*)) const
	{
		DLNode<T> *p;
		p = Head->next;
		while (p != Head)
		{
			v(&p->data);
			p = p->next;
		}
		cout << endl;
	}

	void ListBackTraverse(void(*v)(T*)) const
	{
		DLNode<T> *p = Head->prior;
		while (p != Head)
		{
			v(&p -> data);
			p = p->prior;
		}

		cout << endl;
	}
};


#endif;



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值