什么是单向循环链表
如图所示,单向循环链表是一个方向单一首尾相连的链表
循环链表的增删改查实现
链表的结构设计
typedef int DataType;
typedef struct Node{
DataType data;
struct Node *next;
}Node;
typedef Node *LinkList;
循环链表的创建
Status ListInit(LinkList *list){
/**创建链表步骤
1、判断当前链表是否为空,为空则创建链表,并将next指向自己
2、如果链表不为空,则找到尾节点,然后将为节点的next指向b,b的next指向链表*list
*/
int item;
LinkList a = NULL;//尾节点
LinkList b = NULL;//新节点
printf("请输入数字,0为结束\n");
while (1) {
scanf("%d",&item);
if (item == 0) break;
//判断当前链表是否为空
if (*list == NULL) {
*list = malloc(sizeof(Node));
(*list)->data = item;
(*list)->next = *list;
}else{
//将当前的值插入到链表末尾,并将新值得next指向首节点
for (a = *list; a->next != *list; a = a->next);
b = malloc(sizeof(Node));
b->data = item;
b->next = *list;
a->next = b;
}
}
return SUCCESS;
}
上面的代码是利用循环的方式找到尾节点,这样就增加了时间的复杂度,也可以用一个临时变量来记录一下尾节点。
循环链表插入数据
Status ListInsert(LinkList *list){
/**
插入步骤:
1、创建一个临时节点b,并判断是否创建成功
2、判断插入位置是否是第一个。
2.1、如果是第一个,就要找到最后一个尾节点a
2.2、将尾节点a的next指向新节点
2.3、将新节点b的next指向*list
3、如果不是第一个
3.1、循环遍历,找到插入位置的前一个节点a
3.2、将新节点b的next指向a的next
3.3、将前一个节点a的next指向新节点b
*/
if (!list) return ERROR;
int index,value,i;
LinkList a,b;//a为插入位置的前一个节点,b为新插入的节点
printf("请输入要插入的位置和值,中间用,隔开:\n");
scanf("%d,%d",&index,&value);
//判断插入位置是否是第一个
b = malloc(sizeof(Node));
if (!b) return ERROR;
if (index == 1) {
for (a = *list; a->next != *list; a = a->next);
b->data = value;
b->next = *list;
a->next = b;
*list = b;
}else{
if (!b) return ERROR;
for (i = 1,a = *list;a->next != *list && i < index-1 ; a=a->next,i++);
b->data = value;
b->next = a->next;
a->next = b;
}
return SUCCESS;
}
循环链表删除数据
Status ListDelete(LinkList *list){
/**
循环链表的删除步骤
1、判断删除的位置是否是第一个
1.1、如果是第一个,然后判断链表的next是否指向自己
1.2、如果是,则将list赋值为NULL。
1.3、如果不是,则找到最后一个尾节点,并且将链表的第一个节点给临时节点b,
然后将链表的第一个节点赋值为b->next,在将尾节点的next指向新的头节点
1.4、释放临时节点b
2、如果不是第一个
2.1、找到需要删除的位置的前一个节点a
2.2、临时变量b赋值为a的next(b即为要删除的节点)
2.3、a的next赋值b的next
2.4、释放临时节点b
*/
if (!list) return ERROR;
int index,i;
LinkList a,b;
printf("请输入要删除的位置\n");
scanf("%d",&index);
if (index == 1) {
if ((*list)->next == *list) {
*list = NULL;
return SUCCESS;
}
for (a = *list; a->next != *list; a = a->next);
b = *list;
*list = b->next;
a->next = *list;
free(b);
}else{
for (i = 1 ,a = *list; a->next != *list && i < index-1; a = a->next,i++);
b = a->next;
a->next = b->next;
free(b);
}
return SUCCESS;
}
循环链表修改数据
Status ChangeValue(LinkList *list){
/**
循环链表的修改值的步骤
1、先判断链表是否为空
2、新建临时变量,并赋值链表的第一个节点
3、找到要修改的值的节点a
4、将新值赋给a的data
*/
if (!*list) return ERROR;
printf("请输入要修改的位置和值,用,隔开\n");
int value,index,i;
LinkList a = *list;
scanf("%d,%d",&index,&value);
for (i = 1; i<index && a->next != *list; i++,a = a->next);
a->data = value;
return SUCCESS;
};
循环链表查找数据
Status FindValue(LinkList list){
/**
循环链表查找的步骤
1、先判断链表是否为空
2、找到需要查找的节点
3、输出节点的内容
*/
if (list) return ERROR;
printf("请输入要查找的值\n");
int value,i = 1;
scanf("%d",&value);
while (value != list->data && list->next != list) {
i++;
list = list->next;
}
printf("查询的值为第%d位\n",i);
return SUCCESS;
};