在双向链表的结点中有两个指针域,一个指向直接后继, 另一个指向直接前驱。
双向循环链表的C语言实现
头文件
#include<stdio.h>
#include<stdlib.h>
//结果函数状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define MAXSIZE 100 //顺序表可能达到的最大长度
typedef int Status;// Status--函数的类型,其值是函数结果的状态代码
typedef char ElemType;
typedef struct DuLNode //声明节点类型和指向节点的指针类型
{
ElemType data; //节点的数据域
struct DuLNode *next, *prior; //节点的指针域
}DuLnode, *DuLinkList; //LinkList为指向结构体Lnode的指针类型
双向循环链表的初始化
Status InitList(DuLinkList L) //双向循环的初始化
{
L = (DuLinkList)malloc(sizeof(DuLnode));
L->next = L;
L->prior = L;
return OK;
}
判断双向循环链表是否为空
int ListEmpty(DuLinkList L)
{
if(L->next == L) return 1; //空表返回1
else return 0; //非空返回0
}
销毁双向循环链表
Status DestroyList(DuLinkList L) //销毁双向循环链表
{
DuLnode *p, *q = L;
while(p!=L)
{
p = q;
q = q->next;
printf("%c,",p->data);
free(p);
}
printf("销毁成功!!!\n");
return OK;
}
清空双向循环链表
Status ClearList(DuLinkList L) //清空双向循环链表
{
DuLnode *p, *q = L->next;
while(p!=L)
{
p = q;
q = q->next;
printf("%c,",p->data);
free(p);
}
L->next = L;
L->prior = L;
printf("清空成功!!!\n");
return OK;
}
求双向循环链表表长
int GetLength(DuLinkList L) //求双向循环链表表长
{
DuLnode *p = L->next;
int i=0;
while(p!=L)
{
i++;
p = p->next;
}
return i;
}
输出显示双向循环链表,1为正向输出,0为反向输出
void ShowList(DuLinkList L, int status)
{
DuLnode *p;
if(status)
{
p = L->next;
while(p!=L)
{
printf("%c,", p->data);
p = p->next;
}
}
else
{
p = L->prior;
while(p!=L)
{
printf("%c,", p->data);
p = p->prior;
}
}
printf("\n");
}
获取双向循环链表第 i 个位置的元素,放入e中
Status GetElem(DuLinkList L, int i, ElemType *e)
{
DuLnode *p = L->next;
int j = 1;
while(p!=L && j<i)
{
p = p->next;
j++;
}
if(p==L && j>i) return FALSE;
*e = p->data;
return OK;
}
按值查找,返回地址或位置, num存放位置, p存放地址
Status LocateElem(DuLinkList L, ElemType e, int *num, DuLnode *p)
{
p = L->next;
int i = 1;
while(p!=L && p->data!=e)
{
p = p->next;
i++;
}
if(p!=L)
{
*num = i;
return OK;
}
else return FALSE;
}
在第i个节点前插入值为e的新节点
Status ListInsert(DuLinkList L, int i, ElemType e)
{
DuLnode *p = L->next;
int j = 1;
while(p!=L && j<i-1) //找到第 i-1个节点
{
p = p->next;
j++;
}
if(p==L && j>i-1) return ERROR;
DuLnode *s = (DuLinkList)malloc(sizeof(DuLnode));
s->data = e;
s->next = p->next;
p->next->next->prior = s;
p->next = s;
s->prior = p;
return OK;
}
删除第i个节点,利用e保存删除结点数据
Status ListDelete(DuLinkList L, int i, ElemType *e)
{
DuLnode *q, *p = L->next;
int j = 1;
while(p!=L && j<i-1) //找到第 i-1个节点
{
p = p->next;
j++;
}
if(p==L && j>i-1) return ERROR;
q = p->next;
p->next = q->next;
q->next->next->prior = p;
*e = q->data;
free(q);
printf("删除成功, %c\n", *e);
return OK;
}
双向循环链表的创建----头插法
DuLinkList CreatList_Head(int n) //双向循环链表的创建----头插法
{
DuLinkList L = (DuLinkList)malloc(sizeof(DuLnode));
DuLnode *p, *q;
L->next = L;
L->prior = L;
q = L; //q指向第一个节点
char i;
int j = 0;
for(i='h';j<n;i--,j++)
{
p = (DuLinkList)malloc(sizeof(DuLnode));
p->data = i;
L->next = p;
p->next = q;
p->prior = L;
q->prior = p;
q = p;
}
return L;
}
双向循环链表的创建----尾插法
DuLinkList CreatList_Tail(int n) //双向循环链表的创建----尾插法
{
DuLinkList L = (DuLinkList)malloc(sizeof(DuLnode));
DuLnode *p, *q;
L->next = L;
L->prior = L;
q = L; //q指向尾结点
char i;
int j = 0;
for(i='a';j<n;i++,j++)
{
p = (DuLinkList)malloc(sizeof(DuLnode));
p->data = i;
p->next = L;
p->prior = q;
q->next = p;
L->prior = p;
q = p;
}
return L;
}
主函数
int main()
{
Status InitList(DuLinkList L); //双向循环的初始化
int ListEmpty(DuLinkList L); //判断链表是否为空
Status DestroyList(DuLinkList L); //销毁双向循环链表
Status ClearList(DuLinkList L); //清空双向循环链表
int GetLength(DuLinkList L); //求双向循环链表表长
Status GetElem(DuLinkList L, int i, ElemType *e); //获取双向循环链表第 i 个位置的元素,放入e中
Status LocateElem(DuLinkList L, ElemType e, int *num, DuLnode *p); //按值查找,返回地址或位置, num存放位置, p存放地址
Status ListInsert(DuLinkList L, int i, ElemType e); //在第i个节点前插入值为e的新节点
Status ListDelete(DuLinkList L, int i, ElemType *e); //删除第i个节点,利用e保存删除结点数据
void ShowList(DuLinkList L, int status); //输出显示双向循环链表,1为 正向输出,0为反向输出
DuLinkList CreatList_Head(int n); //双向循环链表的创建----头插法
DuLinkList CreatList_Tail(int n); //双向循环链表的创建----尾插法
DuLinkList L;
L = CreatList_Head(8); //头插法创建链表
// L = CreatList_Tail(8); //尾插法创建链表
if(!ListEmpty(L)) //判断链表是否为空
{
printf("非空\n");
}
else printf("空\n");
ShowList(L, 1); //正向输出链表
ShowList(L, 0); //反向输出链表
printf("链表表长为:%d\n", GetLength(L));
printf("表尾元素为:%c\n",L->prior->data);
printf("表头元素为:%c\n",L->next->data);
int i = 5, loc;
DuLnode p;
ElemType e1, e = 'c', e2;
GetElem(L, i, &e1);
printf("第%d个节点的值为:%c\n", i, e1);
LocateElem(L, e, &loc, &p);
printf("%c所在节点的位置为:%d,地址为%d\n", e, loc, &p);
ListDelete(L, i, &e2);
ShowList(L, 1);
ListInsert(L, i, e2);
ShowList(L, 1);
}