代码如下:
#include <stdio.h>
#include <stdlib.h>
// 声明循环单链表的结构体
struct CLNode {
int data;
struct CLNode *next;
};
// 创建一个循环单链表 */
/* *&L指的是要创建的单链表;a[]指的是要批量添加的整数数组;n指的是数组长度 */
void createClist(CLNode *&L,int a[],int n) {
CLNode *temp,*node;
// 创建一个带头结点的单链表
L=(CLNode *)malloc(sizeof(CLNode));
L->next=NULL;
temp=L; // 尾指针
for(int i=0; i<n; i++) { // 循环添加结点
node=(CLNode *)malloc(sizeof(CLNode)); // 新建结点
node->data=a[i]; // 为结点赋数据值
temp->next=node; // 连接上新添加的结点
temp=node; // 将尾指针指向新添加的结点
}
temp->next=L; // 循环单链表的核心代码。将尾指针的下一个结点指向头结点
}
// 打印一个循环单链表 */
/* *L指的是要被打印的循环单链表 */
void printList(CLNode *L) {
CLNode *temp;
temp=L->next;
printf("\n");
while(temp!=L) { // 循环的条件是是否等于头指针
printf("%d\t",temp->data);
temp=temp->next;
}
printf("\n");
}
/* 求循环单链表的表长的算法 */
/* *L指的是循环单链表 */
int length(CLNode *L) {
int i=0;// 计数器,统计结点个数
CLNode *temp=L->next;
while(temp!=L) {
i++;
temp=temp->next;
}
return i;
}
/* 通过值查找结点的算法 */
/* *list指的是循环单链表;x指的是要查找的值 */
CLNode * findNode(CLNode *list,int x) {
CLNode *temp=list->next;
while(temp!=list) {
if(temp->data==x) {
break;
}
temp=temp->next;
}
return temp;
}
/* 通过序号(不是下标)查找结点的算法 */
/* *list指的是双链表;p指的是要查找的序号 */
CLNode * find(CLNode *list,int pos) {
CLNode *temp=list->next;
int i=1; // 计数器,记录当前结点的序号(不是下标)
while(temp!=list&&i<pos) {
i++;
temp=temp->next;
}
if(i==pos) {
return temp;
} else {
return NULL;
}
}
/* 在循环单链表的指定序号位置(不是下标)插入新结点 */
/* *&list指的是要操作的循环单链表;pos指的是要插入的序号位置(不是下标);data指的是数据值 */
void insert(CLNode *&list,int pos,int data) {
CLNode *temp=list->next;
CLNode *priorNode,*node;
/* 分情况讨论:(1)插入位置是首位;(2)插入位置不是首位 */
/* (1)插入位置是首位 */
if(pos==1) {
node=(CLNode *)malloc(sizeof(CLNode));
node->data=data;
node->next=temp;
list->next=node;
return;
}
/* (2)插入位置不是首位 */
priorNode=find(list,pos-1);
if(priorNode==NULL) {
printf("第%d个结点不存在!",pos-1);
} else if(priorNode->next==NULL) {
printf("第%d个结点不存在!",pos);
} else {
node=(CLNode *)malloc(sizeof(CLNode));
node->data=data;
node->next=priorNode->next;
priorNode->next=node;
}
}
/* 删除循环单链表指定序号位置(不是下标)的结点 */
/* *&list指的是要操作的循环单链表;pos指的是要插入的序号位置(不是下标) */
void deleteNode(CLNode *&list,int pos) {
CLNode *temp=list->next; // 即为开始结点
CLNode *tempDelNode,*priorNode;// *tempDelNode用于临时保存要被删除的结点;*priorNode用于保存要删除结点前一个结点的指针信息
/* 分情况讨论:(1)删除位置是首位;(2)删除位置不是首位 */
/* (1)删除位置是首位 */
if(pos==1) { // 处理删除序号位置是首位的情况
tempDelNode=temp; // 临时保存开始结点(即第一个结点也就是要被删除结点)的指针
list->next=tempDelNode->next; // 将头指针的下一个结点(即开始结点)指向要被删除结点的下一个结点(即原链表中的第二个结点)
free(tempDelNode);// 释放结点资源
return; // 退出
}
/* (2)删除序号位置不是首位 */
priorNode=find(list,pos-1); // 获取要被删除结点的前一个结点的指针
if(priorNode==NULL) {
printf("第%d个结点不存在!",pos-1);
} else if(priorNode->next==NULL) {
printf("第%d个结点不存在!",pos);
} else {
tempDelNode=priorNode->next; // 临时保存被删除结点
priorNode->next=tempDelNode->next; // 将被删除结点的前一个结点的指针指向被删除结点的下一个结点
free(tempDelNode);// 释放被删除结点的资源
}
}
int main() {
CLNode *list,*t1,*t2;
/* [0.]创建初始测试循环单链表 */
int a[]= {1,3,5,7,9};
createClist(list,a,5);
/* [1.]打印循环单链表 */
printList(list);
/* [2.]循环单链表的长度 */
printf("\n%d\n",length(list)); // 打印循环单链表list的长度
/* [3.]查找结点 */
t1=findNode(list,7); // 在循环单链表list中查找值为7的结点
printf("\n%d\n",t1->data);
/* [4.]按序号查找结点 */
t2=find(list,3); // 在循环单链表list中查找序号为3的结点,返回该结点指针
printf("\n%d\n",t2->data);// 返回返回结点的数据data
/* [5.]插入新结点 */
insert(list,1,99);// 在链表序号为1的位置新增加一个data值为99的新结点
printList(list);
/* [6.]删除结点 */
deleteNode(list,1);// 删除链表中序号为1的结点
printList(list);
return 0;
}
运行结果如下图: