# 数据结构之单循环链表(三)
2020-04-02 本文已影响0人
大橘猪猪侠
一、循环链表的定义
循环链表是另一种形式的链式存贮结构。它的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环。
单循环链表——在单链表中,将终端结点的指针域NULL改为指向表头结点或开始结点即可。
通常对链表的操作有
1、创建链表
2、取值操作
3、查找操作
4、插入操作
5、删除操作
6、遍历操作
图为一个单向循环链表
15857963061859.png
首先我们来创建一个链表
2. int item;
3. Linklist temp=NULL,r = NULL;
4. printf("输入节点的值,输入0结束\n");
5. while (1) {
6. scanf("%d",&item);
7. if(item==0)break;
8. //如果链表为空,则创建一个新节点,将新节点指向自己
9. if(*L==NULL){
1. *L = (Linklist)malloc(sizeof(Node));
2. if(!L)return ERROR;
3. (*L)->data = item;
4. (*L)->next = *L;
5. r = *L;
6. }else{
7. temp = (Linklist)malloc(sizeof(Node));
8. if(!temp)return ERROR;
9. temp->data = item;
1. //将新节点指向头节点
2. temp->next = *L;
3. //将尾部节点指向新节点
4. r->next = temp;
5. r = temp;
6. }
7. }
8. return OK;
9. }
对链表进行遍历
2. void showLinklist(Linklist L){
3. //如果链表为空
4. if(L == NULL){
5. printf("打印链表为空!\n");
6. return;
7. }else{
8. Linklist temp;
9. temp = L;
1. do {
2. printf("%5d",temp->data);
3. temp = temp->next;
4. }while(temp!=L);
5. printf("\n");
6. }
7. }
循环链表的插入
情况一:头节点插入!
15857974834446.png
情况二:其他节点插入
截屏2020-04-02上午11.02.57.png
2. Status LinklistInsert(Linklist *L,int place,int num){
3. Linklist temp,target;
4. int I;
5.
6. if(place == 1){
7. /*
8. 如果插入的位置为1,则属于插入首元节点,所以需要特殊处理
9. 1、创建新节点temp,并判断是否创建成功
10. 2、找到链表最后一个尾部节点
11. 3、将新节点的next指向头节点
12. 4、将尾部节点的next指向新的头节点
13. 5、将头指针指向新节点
14. */
15. temp = malloc(sizeof(Node));
16. if(temp == NULL) return ERROR;
17. temp -> data = num;
18. target = *L;
19. while (target->next!=*L) {
20. target = target->next;
21. }
22. temp -> next = *L;
23. target->next = temp;
24. *L = temp;
25. }else{
26. /*
27. 如果插入的位置在其他位置
28. 1、创建新节点temp,并判断是否创建成功
29. 2、先找到插入点的位置,若超过链表长度,自动插入尾部
30. 3、通过target找到要插入的位置的前一个节点,让target->next = temp;
31. 4、让插入节点的前驱指向新节点,让新节点的next指向target的next
32. */
33. temp = malloc(sizeof(Node));
34. if(temp == NULL) return ERROR;
35. temp -> data = num;
36. for (i = 1,target = *L; target->next!=*L&&i!=place-1; target = target->next,i++);
37. temp->next = target->next;
38. target->next = temp;
39. }
40. return OK;
41. }
链表的删除
1. Status LinklistDelete(Linklist *L,int place){
2.
3. Linklist temp,target;
4. int I;
5. int num = 0;
6. //让temp指向首元节点
7. temp = *L;
8. if(temp == NULL)return ERROR;
9. if(place == 1){
10. //1、如果删除到只剩下首元节点,直接将L置空
11. if((*L)->next == (*L)){
12. num = (*L)->data;
13. (*L) = NULL;
14. return OK;
15. }
16. /*2、链表还有很多数据,但是删除的是首节点
17. 1、找到尾部节点,使尾部节点next指向头节点的下一个节点
18. 2、将头节点的下一个节点置为头节点,将原来的头节点释放
19. */
20. target = *L;
21. while (target -> next!=*L) {
22. target = target->next;
23. }
24. temp = *L;
25. *L = (*L)->next;
26. target ->next = *L;
27. num = temp->data;
28. free(temp);
29. }else{
30. /*
31. 如果删除的是其他节点
32. 1、找到删除的节点的前一个节点target
33. 2、使target->next指向删除节点的下一个节点
34. 3、释放所删除的节点
35. */
36. if((*L) ->next == (*L)){
37. num = (*L)->data;
38. free(*L);
39. return OK;
40. }
41.
42. for (i=1,target=*L; target->next!=*L&&i!=place-1; target = target->next,i++);
43. if(i<place-1)
44. return ERROR;
45. temp = target->next;
46. target->next = temp->next;
47. num = temp->data;
48. free(temp);
49. }
50. printf("删除的节点是:%d\n",num);
51. return OK;
52. }
链表值的查找
2. int i = 1;
3. Linklist p;
4. p = L;
5. //寻找链表中的节点
6. while (p->data!=value && p->next != L) {
7. I++;
8. p = p->next;
9. }
10. if(p->next == L && p->data !=value){
11. return -1;
12. }
13. return I;
14. }
main函数调用方法
2. Linklist head;
3. int place,num;
4. int isStatus;
5.
6. isStatus = CreateLinklist(&head);
7. printf("原始链表:\n");
8. showLinklist(head);
9. printf("\n");
10.
11. printf("请输入要插入节点的位置和值:\n");
12. scanf("%d %d",&place,&num);
13. isStatus = LinklistInsert(&head, place, num);
14. showLinklist(head);
15. printf("\n");
16.
17. printf("请输入要删除的节点的位置");
18. scanf("%d",&place);
19. isStatus = LinklistDelete(&head, place);
20. showLinklist(head);
21. printf("\n");
22.
23. printf("请输入你要查找的值:");
24. scanf("%d",&num);
25. place = findValue(head, num);
26. if(place!=-1)
27. printf("找到的值的位置是place = %d\n",place);
28. else
29. printf("没找到值\n");
打印结果
15857977932572.png
第一次用markdown,不太会用
有错误的地方请指出,谢谢!