说明
循环单链表最后一个结点的指针指向头结点,整个链表形成一个环。在循环链表中,从任意一个结点出发都可以找到其他结点。
代码
/*
** cslink create by yubo.wang 2018.9.12
*/
#include <stdio.h>
#include <stdlib.h>
typedef char ElemType;
typedef struct node
{
ElemType data;
struct node *next;
}SLink;
SLink *MaxNode(SLink *L);
void InitList(SLink *&L) /*SLink *&L作为引用型参数或者用二级指针SLink **L*/
{
L=(SLink *)malloc(sizeof(SLink));
L->next = L;
}
int GetLength(SLink *L)
{
int i=0;
SLink *p=L->next;
while(p != L)
{
i++;
p=p->next;
}
return i;
}
int GetElem(SLink *L,int i,ElemType &e)
{
int j=1;
SLink *p=L->next;
if(i<1 || i>GetLength(L))
return 0;
while(j<i)
{
p=p->next;
j++;
}
e=p->data;
return 1;
}
int Locate(SLink *L,ElemType x)
{
int i=1;
SLink *p=L->next;
while(p!=L && p->data!=x)
{
p=p->next;
i++;
}
if(L == p)
return 0;
else
return i;
}
int InsElem(SLink *L,ElemType x,int i)//初始化是尾插,也可中途插入
{
int j=1;
SLink *p=L,*s;
s=(SLink *)malloc(sizeof(SLink));
s->data=x;
s->next=NULL;
if(i<1 || i>GetLength(L)+1)//防止i越界
return 0;
while(j<i)
{
p=p->next;
j++;
}
s->next = p->next;
p->next = s;
return 1;
}
int DelElem(SLink *L,int i)
{
int j=1;
SLink *p=L,*q;
if(i<1 || i>GetLength(L))
return 0;
while(j<i)
{
p=p->next;
j++;
}
q=p->next;
printf("%c\n", q->data);
p->next=q->next;
free(q);
return 1;
}
void DispList(SLink *L)
{
SLink *p=L->next;
while(p != L)
{
printf("%c ", p->data);
p=p->next;
}
printf("\n");
}
int main()
{
int i;
ElemType e;
SLink *L=NULL;
InitList(L);//initial head
InsElem(L,'a',1);
InsElem(L,'b',2);
InsElem(L,'c',3);
InsElem(L,'d',4);
InsElem(L,'e',5);
InsElem(L,'f',6);
printf("List:");
DispList(L);
printf("Length: %d\n", GetLength(L));
i=3;
GetElem(L,i,e);
printf("index %d data is:%c\n", i,e);
e='e';
printf("data %c index is: %d\n", e,Locate(L,e));
i=4;
printf("delete index %d data ", i);
DelElem(L,i);
i=2;
e='w';
printf("insert index %d data %c\n", i, e);
InsElem(L,e,2);
printf("List:");
DispList(L);
printf("MaxNode:%c\n", MaxNode(L)->data);
}
/*通过一趟遍历返回单链表元素最大值的结点*/
SLink *MaxNode(SLink *L)
{
SLink *p=L->next,*q=p;//p用来遍历,q用来记录最大的值结点
while(p != L)
{
if(p->data > q->data)
q=p;
p=p->next;
}
return q;
}
/*ha hb两个带头结点的循环链表首尾合并为一个带头结点的循环链表hc,不改变ha hb*/
SLink *link(SLink *ha,SLink *hb)
{
SLink *hc,*p,*s,*tc;
hc=(SLink *)malloc(sizeof(SLink));//建立hc的头结点
tc=hc;//tc始终指向hc的最后一个结点
p=ha->next;
while(p != ha)//将ha的结点复制到hc中
{
s=(SLink *)malloc(sizeof(SLink));
s->data = p->data;
tc->next=s;
tc=s;
p=p->next;
}
p=hb->next;
while(p != hb)//将hb的结点复制到hc中
{
s=(SLink *)malloc(sizeof(SLink));
s->data = p->data;
tc->next=s;
tc=s;
p=p->next;
}
tc->next=hc;//将hc变为循环单链表
return hc;
}