第一次在CSDN这边写博客,主要是为了记录自己学习的历程,望诸位共勉。
首先循环链表是神魔恋?其实就是为了解决单链表只能从头开始过于麻烦诞生的,我愿称之为单链表2.0。(所以如果搞不清楚的话建议先学一下单链表。)
那么它和单链表之间是什么关系,单链表的结尾指向的是一个空节点,存着NULL这个空值。那么他在索引的时候出现的问题显而易见,如果你不从头结点开始那你就无法访问全部结点。
循环链表的设计者明显就很鬼才了,我把最后一个结点的指向变成头节点不就可以了,这样我就可以从想开始的地方开始索引,而且都能保证索引到全部结点,然后这个链表就像贪吃蛇咬到自己尾巴一样闭环了,就叫(单)循环链表。
下面贴出代码的具体实现,如有不对欢迎指正。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<stdlib.h>
#include<time.h>
#define ERROR 0
#define OK 1
typedef int EleType;
typedef struct CLinkNode
{
EleType data;
struct CLinkNode *next;
}CLinkNode, *CLinkList;
//初始化循环链表
int InitCLinkList(CLinkList *list)
{
if (list == NULL)//判断指针是否为空
{
return ERROR;
}
CLinkNode* head_node=NULL;//定义头节点,但是循环链表不一定非要定义头节点。
CLinkNode* target=NULL;//定义工具人结点。
int item = 0;//定义结点存储值
printf("请输入初始化数据,输入0结束\n");
while (1)
{
scanf_s("%d", &item);
fflush(stdin);
if (item == 0)
break;
if (*list == NULL)//判断表是否为空若为空,若为空就生成头节点并用它指向第一个含元素的结点,头节点是没有值的
{
CLinkNode* head = (CLinkNode*)malloc(sizeof(CLinkNode));
if (head == NULL)
exit(0);
*list = head;
CLinkNode* temp = (CLinkNode*)malloc(sizeof(CLinkNode));
temp->data = item;
temp->next=head;
head->next=temp;
}
//表不为空就不断将工具人结点变成最后一个结点并实现尾插的操作
else {
for (target = *list; target->next != *list; target = target->next);
head_node = *list;
CLinkNode* temp = (CLinkNode*)malloc(sizeof(CLinkNode));
if (temp == NULL)
exit(0);
temp->data = item;
temp->next = head_node;
target->next = temp;
}
}
return OK;
}
//插入操作,由于使用了头节点所以我们并不需要去判断第一个元素是否是头节点,因为第一个元素的下标事实上是2
int insert(CLinkList list)
{
if (list == NULL)
{
return ERROR;
}
int j = 1;
int item=0;
int local = 0;
CLinkNode *target =list;
CLinkNode *temp = NULL;
printf("请输入插入位置");
scanf_s("%d", &local);
fflush(stdin);
while (target->next != list&&j < local)
{
target = target->next;
j++;
}
//只有当j和位置变量的值相等时他才是真正的插在了这个位置,用此来判断非法插入。
if (j == local) {
printf("请输入插入数据");
scanf_s("%d", &item);
temp = (CLinkNode*)malloc(sizeof(CLinkNode));
if (temp == NULL)
{
exit(0);
}
temp->data = item;
temp->next = target->next;
target->next = temp;
}
else
{
printf("插入位置有误\n");
return ERROR;
}
return OK;
}
//删除操作,这里只写用位置实现删除操作,想从数据进行索引的可以参考此段代码进行。
int deleteitem(CLinkList list) {
if (list == NULL)
return ERROR;
int local = 0;
int j = 1;
printf("请输入删除元素的位置");
scanf_s("%d", &local);
CLinkNode* target = list;
while (target->next != list&&j < local)
{
target = target->next;
j++;
}
if (j = local)
{
CLinkNode* temp = target->next;//temp是实际上将删除的结点
target->next = temp->next;//由于它的上司直接接管了它的下属所以它被架空了
free(temp);//最后对它进行人道主义毁灭
}
else {
printf("输入位置有误");
return ERROR;
}
return OK;
}
//查找,这是最简单的一个操作了也没什么好讲的,这里是从头结点开始索引,有兴趣也可以做一个从中间元素开始索引的。
int find(CLinkList list)
{
if (list == NULL)
{
return ERROR;
}
int local = 0;
printf("请输入查找的位置");
scanf_s("%d", &local);
CLinkNode *target = list->next;
int i = 1;
while (target->next != list&&i < local)
{
target = target->next;
i++;
}
if (i == local)
{
printf("查找%d位置的元素为%d\n", local, target->data);
}
else {
printf("输入查找位置有误\n");
return ERROR;
}
return OK;
}
//打印操作
int show(CLinkList list)
{
if(list == NULL)
{
return ERROR;
}
CLinkNode* target = NULL;
printf("循环链表中的元素为\n");
for (target = list->next; target != list; target = target->next)
printf("%d ", target->data);
printf("\n");
return OK;
}
//主函数。
void main()
{
CLinkList list=NULL;//声明循环链表为空
int x =1;
printf("1.创建循环链表\n");
printf("2.插入数据\n");
printf("3.输出链表\n");
printf("4.查找\n");
printf("5.删除某位置元素\n");
while (x != 0) {
printf("请选择\n");
scanf_s("%d", &x);
switch (x)
{
case 1: {
printf("正在创建\n");
InitCLinkList(&list);
show(list);
break; };
case 2:insert(list);
show(list);
break;
case 3:show(list);
break;
case 4:deleteitem(list);
show(list);
break;
case 5: find(list);
break;
default:
printf("输入有误请重新选择\n");
break;
}
}
}
来源:CSDN
作者:goldenzhouzhuo
链接:https://blog.csdn.net/goldenzhouzhuo/article/details/104703352