数据结构(循环链表)
数据结构(循环链表)
循环单链表和循环双链表的结点类型,与非循环单链表,非循环双链表一致。
单链表改为循环单链表的过程是将它尾结点的next指针域由原来的空NULL改为指向头结点L。
双链表改为循环双链表示将尾结点的next指针域由原来的空NULL改为指向头结点L,同时将头结点的prior指针域改为指向尾结点。
故,循环链表的基本运算的实现算法与对应非循环链表的算法基本相同,差别在于判断表尾结点p的条件变为p->next==L,另外循环双链表可以通过L->prior快速找到尾结点。
以下是书本的体验代码
//
// Created by Snow on 2023/3/6.
//
//循环链表
#include<cstdio>
#include<cstdlib>
typedef int ElemType;
typedef struct LNode
{
ElemType data;//存放元素值
struct LNode *next;//指向后继节点
}LinkNode;//单链表结构类型
typedef struct DNode
{
ElemType data;
struct DNode *prior;
struct DNode *next;
}DLinkNode;
//尾插法建立单链表(顺序)
void CreatListR(LinkNode *&L,ElemType arr[],int n)
{
LinkNode *s,*r;
L=(LinkNode *)malloc(sizeof(LinkNode));//创建头结点
r=L;//r始终指向尾结点,初始时指向头结点
for(int i=0;i<n;i++)//循环建立数据节点
{
s=(LinkNode *)malloc(sizeof(LinkNode));
s->data=arr[i];//创建数据节点s
r->next=s;//将节点s插入节点r之后
r=s;
}
r->next=L;//将尾结点的指针域置为NULL
}
//尾插法建立双链表
bool CreatListR(DLinkNode *&L,ElemType arr[],int n)
{
DLinkNode *s,*r;
L=(DLinkNode *)malloc(sizeof(DLinkNode));
r=L;
for(int i=0;i<n;i++)
{
s=(DLinkNode *)malloc(sizeof(DLinkNode));
s->data=arr[i];
r->next=s;
s->prior=r;
r=s;
}
r->next=L;
L->prior=r;
return true;
}
//统计data域值为x的结点个数
int count(LinkNode *L,ElemType x)
{
int cnt=0;
LinkNode *p=L->next;
while(p!=L)
{
if(p->data==x)cnt++;
p=p->next;
}
return cnt;
}
//删除双链表中第一个data域值为x的结点
bool DelElem(DLinkNode *&L,ElemType x)
{
DLinkNode *p=L->next;
while(p!=L&&p->data!=x)
p=p->next;
if(p!=L)
{
p->next->prior=p->prior;
p->prior->next=p->next;
free(p);
return true;
}
else return false;
}
//查看循环双链表中的数据结点是否对称
bool Symm(DLinkNode *L)
{
bool same=true;
DLinkNode *p=L->next;
DLinkNode *q=L->prior;
while(same)
{
if(p->data!=q->data)
same=false;
else
{
if(p==q||p==q->prior)break;
p=p->next;
q=q->prior;
}
}
return same;
}
//销毁线性表
void DestroyList(LinkNode *&L)
{
LinkNode *pre=L,*p=L->next;//pre指向结点p的前驱结点
while(p!=L)//遍历单链表L
{
free(pre);//释放pre结点
pre=p;//pre,p同步后移一个结点
p=p->next;
}
free(pre);//循环结束时p为NULL,pre指向尾结点,释放他
}
bool DestroyList(DLinkNode *&L)
{
DLinkNode *pre=L,*p=L->next;
while(p!=L)
{
free(pre);
pre=p;
p=p->next;
}
free(pre);
return true;
}
//输出线性表
void DispList(LinkNode *L)
{
LinkNode *p=L->next;//p指向首结点
while(p!=L)//p不为NULL,输出p结点的data域
{
printf("%d ",p->data);
p=p->next;//p移动下一个结点
}
printf("\n");
}
bool DispList(DLinkNode *L)
{
if(L==NULL)return false;
DLinkNode *p=L->next;
while(p!=L)
{
printf("%d ",p->data);
p=p->next;
}
printf("\n");
return true;
}
int main()
{
LinkNode *L1;
DLinkNode *L2;
ElemType arr[]={1,2,3,3,2,1};
CreatListR(L1,arr,6);
DispList(L1);
printf("%d\n", count(L1,2));
DestroyList(L1);
CreatListR(L2,arr,6);
DispList(L2);
if(Symm(L2))printf("yes\n");
DelElem(L2,2);
DispList(L2);
return 0;
}