循环链表的概念主要就是让单链表的尾节点的指针不为空并且指向头节点。像这样的循环链表和普通单链表除了判断条件几乎没有任何区别,判断条件就是从p->next是否为空改为p->next是否等于头节点,如果等于头节点则循环结束。
#include <stdio.h>
#include <stdlib.h>
typedef int Eletype;
typedef struct Node{
Eletype data;
struct Node *next;
}Node;
typedef Node *linkList;
void initf(linkList *l){
*l=(linkList)malloc(sizeof(Node));
//因为是循环链表,所以尾指针指向头节点
(*l)->next=*l;
linkList s;
for(int i=0;i<5;i++){
s=(linkList)malloc(sizeof(Node));
s->data=rand()%100+1;
s->next=(*l)->next;
(*l)->next=s;
}
}
void getfELE(linkList l,int index,Eletype *e){
int i=1;
//因为头节点无数据所以p指向l->next
linkList p=l->next;
//因为是循环链表,p没有为空的时候,所以判断条件应为p不指向头节点的时候
while((p!=(l))&&i<index){
p=p->next;
i++;
}
*e=p->data;
}
void insertfELE(linkList *l,int index,Eletype e){
int i=1;
linkList p=*l;
while(p&&i<index){
p=p->next;
i++;
}
linkList s;
s=(linkList)malloc(sizeof(Node));
s->data=e;
s->next=p->next;
p->next=s;
}
void deletefELE(linkList *l,int index){
int i=1;
linkList p=*l;
//因为是循环链表,p没有为空的时候,所以判断条件应为p的next不指向头节点的时候
while((p->next!=(l))&&i<index){
p=p->next;
i++;
}
linkList r=p->next;
p->next=r->next;
free(r);
}
void clearfAll(linkList *l){
linkList q,p=(*l)->next;
//因为是循环链表,p没有为空的时候,所以判断条件应为p不指向头节点的时候
while(p!=(*l)){
q=p->next;
free(p);
p=q;
}
(*l)->next=*l;
}
void displayfLinklist(linkList l){
Eletype e;
for(int i=1;i<10;i++){
getfELE(l,i,&e);
printf("%d ",e);
}
printf("\n");
}
void main(){
linkList s,b;
initf(&s);
displayfLinklist(s);
//测试循环链表是否初始化成功
printf("%d\n",*(s->next->next->next->next->next->next->next));
insertfELE(&s,5,1000);
displayfLinklist(s);
deletefELE(&s,5);
displayfLinklist(s);
clearfAll(&s);
printf("%d\n",*(s->next));
}
将两个循环链表合并在一起需要定义一个尾指针,正常的一个循环链表尾指针指向头节点,将两个循环链表合并则是让第一个尾指针指向第二个链表的第一个数据节点(这里不指向第二个链表的头节点),让第二个尾指针指向第一个链表的头节点。例如有两个循环链表记作A、B,weiA是链表A的尾指针,weiB是链表B的尾指针。合并两个链表的实现代码如下:
p=weiA->next; p代表A的头节点同时也是新链表的头节点
weiA->next=weiB->next->next; 让链表A的尾指针指向链表B的第一个有数据的节点
weiB->next=p; 让链表B的尾指针指向链表A的头节点也就是p
free(p); 将p释放掉
***这里p必须定义