本文主要讲述含有只含有头结点的双向循环链表,其中头文件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;