1、每个元素除了拥有指向后继的指针外,还拥有指向前驱的指针;
2、便于元素的逆向查找和遍历;
3、同时具备循环链表的所有优点。
文件1:utils.h头文件
#ifndef _YE_LELE_02
#define _YE_LELE_02
#include"double_circular_linked_list.h"
//打印星星
void print_star();
//打印链表内容
void myVisit(int x);
#endif
文件2:utils.cpp函数实现
#include
void print_star()
{
printf("**********************\n");
}
void myVisit(int x)
{
printf("%d\n", x);
}
文件3:double_circular_linked_list.h
#ifndef _YE_LELE_01
#define _YE_LELE_01
typedef int ElemType;
typedef int Status;
//双向循环链表的定义
typedef struct DuLNode
{
ElemType data;
struct DuLNode *prior;
struct DuLNode *next;
}DuLNode, *DuLinkList;
void InitList(DuLinkList &L);//循环链表的初始化
void DestoryList(DuLinkList &L);//销毁循环链表
void ClearList(DuLinkList &L);//清空循环链表
Status ListEmpty(DuLinkList L);//判断循环链表元素是否为空
int ListLength(DuLinkList L);//获得循环链表的长度
Status GetElem(DuLinkList L, int loc, ElemType &e);//得到循环链表loc位置的元素并赋值给e
int LocateElem(DuLinkList L, ElemType a);//定位元素a在循环链表的位置
Status PriorElem(DuLinkList L, ElemType a, ElemType &e);//获取链表元素a的前一个节点并赋值给e,返回一个状态
Status NextElem(DuLinkList L, ElemType a, ElemType &e);//获取链表元素a的后一个节点并赋值给e,返回一个状态
Status ListInsert(DuLinkList &L, ElemType a, int loc);//将元素a插入到链表loc的位置
Status ListDelete(DuLinkList &L, ElemType &e, int loc);//删除循环链表loc位置的元素,并将删除的值赋值给e
void ListTraverse(DuLinkList L);//遍历整个循环链表
void ListTraverseBcak(DuLinkList L, void(*visit)(ElemType));//反向遍历整个循环链表
#endif
文件4:double_circular_linked_list.cpp
#include "double_circular_linked_list.h"
#include
#include
//定义状态码
#define ERROE -2
#define OVERFLOW -3
#define OK 1
#define YES 1
#define NO 0
/*
操作结果:产生空的双向链表L,并作为一个不填充数据的空节点
*/
void InitList(DuLinkList &L)//循环链表的初始化
{
L = (DuLinkList)malloc(sizeof(DuLNode));
if (L)
{
//前驱及后继均指向节点自身
L->next = L->prior = L;
}
else
{
//分配失败,内存溢出
exit(OVERFLOW);
}
}
void DestoryList(DuLinkList &L)//销毁循环链表
{
//如果链表本身为空,错误退出
if (!L)
{
exit(ERROE);
}
//释放循环链表指针,释放内存
free(L);
}
void ClearList(DuLinkList &L)//清空循环链表
{
//如果链表本身为空,错误退出
if (!L)
{
exit(ERROE);
}
//重新初始化
InitList(L);
printf("循环链表成功清除!\n");
}
Status ListEmpty(DuLinkList L)//判断循环链表元素是否为空
{
//如果链表本身不存在,错误退出
if (!L)
{
exit(ERROE);
}
//定义一个指针指向首节点
DuLinkList p = L;
if (p->next == L)
{
return YES;
}
return NO;
}
int ListLength(DuLinkList L)//获得循环链表的长度
{
//如果链表本身不存在,错误退出
if (!L)
{
exit(ERROE);
}
DuLinkList p = L;
int count = 0;
while (true)
{
//循环到达首部节点
if (p->next == L)
{
break;
}
p = p->next;
count++;
}
return count;
}
Status GetElem(DuLinkList L, int loc, ElemType &e);//得到循环链表loc位置的元素并赋值给e
int LocateElem(DuLinkList L, ElemType a)//定位元素a在循环链表的位置
{
//定义一个标记,用于指示状态
int flag, loc = 0;
//如果循环链表未初始化,返回错误码
if (!L)
{
return ERROE;
}
//定义一个节点指向循环链表的首节点
DuLinkList p = L;
while (true)
{
//如果在n-1个节点内找到该元素
if (p->next != L)
{
if (p->data == a)
{
flag = 1;
return loc;
}
p = p->next;
loc++;
}
//如果表尾元素等于需要判断的元素
else if (p->next == L&&p->data == a)
{
return loc;
}
//如果没有找到该元素
else
{
flag = -1;
break;
}
}
if (flag == -1)
{
return NO;
}
}
Status PriorElem(DuLinkList L, ElemType a, ElemType &e)//获取链表元素a的前一个节点并赋值给e,返回一个状态
{
if (!L)
{
exit(ERROE);
}
DuLinkList p = L->next;
//获取元素a在循环链表的位置
int position = LocateElem(L, a);
//获取链表的长度
int Length = ListLength(L);
if (position<1)
{
printf("循环链表不存在该元素,无节点值返回\n");
return NO;
}
else
{
for (size_t i = 1; i < position; i++)
{
p = p->next;
}
e = p->prior->data;
}
return OK;
}
Status NextElem(DuLinkList L, ElemType a, ElemType &e);//获取链表元素a的后一个节点并赋值给e,返回一个状态
Status ListInsert(DuLinkList &L, ElemType a, int loc)//将元素a插入到链表loc的位置
{
DuLinkList p = L, s;
int j;
//插入位置不合法
if (loc < 1|| loc > ListLength(L)+1)
{
return ERROE;
}
//移动节点到需要插入的位置
for (j = 1; j <= loc-1; j++)
{
p = p->next;
}
//申请一个节点的空间
s = (DuLinkList)malloc(sizeof(DuLNode));
if (!s)
{
return OVERFLOW;
}
s->data = a;
s->prior = p;
s->next = p->next;
p->next->prior = s;
p->next = s;
return OK;
}
Status ListDelete(DuLinkList &L, ElemType &e, int loc)//删除循环链表loc位置的元素,并将删除的值赋值给e
{
if (!L)
{
exit(ERROE);
}
DuLinkList p = L;
//获取链表的长度
int Length = ListLength(L);
if (loc<1 || loc>Length)
{
printf("删除元素的位置不存在\n");
return ERROE;
}
//为了找到上游位置,loc值提前减去1
loc--;
while (loc)
{
p = p->next;
loc--;
}
e = p->next->data;
p->next = p->next->next;
p->next->next->prior = p;
return OK;
}
void ListTraverse(DuLinkList L)//遍历整个循环链表
{
DuLinkList p = L->next;//让p指向首节点
while (p != L)
{
printf("%d\n", p->data);
p = p->next;
}
}
void ListTraverseBcak(DuLinkList L,void(*visit)(ElemType))//反向遍历整个循环链表
{
DuLinkList p = L->prior;//让p指向尾节点
while (p != L)
{
visit(p->data);
p = p->prior;
}
}
文件5:main.cpp
#include
#include "utils.h"
#include"double_circular_linked_list.h"
int e;
void test_DuListAppend(DuLinkList &L)
{
ListInsert(L, 1, 1);
ListInsert(L, 3, 2);
ListInsert(L, 5, 3);
ListInsert(L, 4, 2);
}
void test_ListTraverseBcak(DuLinkList L)
{
ListTraverseBcak(L,myVisit);
}
void test_ListTraverse(DuLinkList L)
{
ListTraverse(L);
}
void test_ListDelete(DuLinkList L)
{
ListDelete(L, e, 4);
printf("delete ok:");
}
void test_LocateElem(DuLinkList L,ElemType a)
{
int result = LocateElem(L, a);
if (result)
{
printf("元素%d的位置为%d\n", a, result);
}
else
{
printf("元素%d在循环链表中不存在!\n", a);
}
}
void test_PriorElem(DuLinkList L, ElemType a, ElemType &e)
{
int result = PriorElem(L, a, e);
if (result)
{
printf("元素%d位置之前的元素值为%d\n", a, e);
}
}
void main()
{
//1、初始化循环链表
print_star();
DuLinkList L = NULL;
InitList(L);
//2、测试插入元素
print_star();
test_DuListAppend(L);
//3、测试反向打印遍历循环链表的结果
print_star();
test_ListTraverseBcak(L);
//4、测试打印遍历循环链表的结果
print_star();
test_ListTraverse(L);
//5、测试按照位置删除元素
test_ListDelete(L);
test_ListTraverse(L);
//6、测试返回固定元素的位置
print_star();
test_LocateElem(L, 3);
//7、测试返回链表元素a的前一个节点并赋值给e
print_star();
test_PriorElem(L,1,e);
}