循环单链表

循环链表的存储示意图

image.png

定义

image.png

代码实现

  1. // DataElement.h
  2. #ifndef INC_01_DATAELEMENT_H
  3. #define INC_01_DATAELEMENT_H
  4. #define MAX_SIZE 255
  5. // 定义数据元素
  6. typedef struct {
  7. int id;
  8. char * name;
  9. } ElementType;
  10. // 定义顺序表结构
  11. typedef struct {
  12. ElementType datas[MAX_SIZE]; // 顺序表中的数据集合
  13. int length; // 当前顺序表中的元素个数
  14. } SeqList;
  15. #endif
  1. // CircularLinkList.h
  2. #ifndef INC_01_CIRCULARLINKLIST_H
  3. #define INC_01_CIRCULARLINKLIST_H
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include "DataElement.h"
  7. /** 循环链表的结点 **/
  8. typedef struct CircularNode {
  9. ElementType data; // 数据域
  10. struct CircularNode * next; // 指向下一个结点的指针域
  11. } CircularNode;
  12. /** 循环链表结构 **/
  13. typedef struct CircularLinkList{
  14. CircularNode * next; // 指向第一个结点的指针,头指针
  15. int length; // 长度
  16. } CircularLinkList;
  17. /** 在循环链表中插入元素 **/
  18. void InsertCircularLinkList(CircularLinkList * clList, int pos, ElementType element);
  19. /** 打印循环链表的所有元素 **/
  20. void PrintCircularLinkList(CircularLinkList * clList);
  21. /** 打印循环链表的所有元素 **/
  22. void InitCircularLinkList(CircularLinkList * clList, ElementType * dataArray, int length);
  23. /** 删除并返回所删除的元素 **/
  24. ElementType DeleteCircularLinkList(CircularLinkList * clList, int pos);
  25. #endif
  1. // CircularLinkList.c
  2. #include "CircularLinkList.h"
  3. /** 在循环链表中插入元素 **/
  4. void InsertCircularLinkList(CircularLinkList * clList, int pos, ElementType element) {
  5. CircularNode * node = (CircularNode * )malloc(sizeof(CircularNode));
  6. node -> data = element;
  7. node -> next = NULL;
  8. // 插入的是第一个结点
  9. if (pos == 1) {
  10. node -> next = clList -> next;
  11. if (!node -> next) { // 如果插入的链表长度为 0
  12. node -> next = node;
  13. } else { // 如果长度不为 0
  14. CircularNode * lastNode = clList -> next;
  15. for (int i = 1; i < clList -> length ; ++i) {
  16. lastNode = lastNode -> next;
  17. }
  18. lastNode -> next = node;
  19. }
  20. clList -> next = node;
  21. clList -> length++;
  22. return;
  23. }
  24. // 插入的不是第一个结点
  25. CircularNode * currNode = clList -> next;
  26. for (int j = 1; currNode && j < pos - 1; ++j) {
  27. currNode = currNode -> next;
  28. }
  29. if (currNode) {
  30. node -> next = currNode -> next;
  31. currNode -> next = node;
  32. clList -> length++;
  33. if (pos == clList -> length) {
  34. node -> next = clList -> next;
  35. }
  36. }
  37. };
  38. /** 打印循环链表的所有元素 **/
  39. void PrintCircularLinkList(CircularLinkList * clList){
  40. if (clList -> length == 0 || !clList -> next) {
  41. printf("链表长度为空,没有内容可以打印!");
  42. clList -> length = 0;
  43. return;
  44. }
  45. CircularNode * node = clList -> next;
  46. for (int i = 0; i < clList -> length; ++i) {
  47. printf("%d\t%s\n", node -> data.id, node -> data.name);
  48. node = node -> next;
  49. }
  50. };
  51. /** 打印循环链表的所有元素 **/
  52. void InitCircularLinkList(CircularLinkList * clList, ElementType * dataArray, int length) {
  53. for (int i = 0; i < length; ++i) {
  54. InsertCircularLinkList(clList, i + 1, dataArray[i]);
  55. }
  56. };
  57. /** 删除并返回所删除的元素 **/
  58. ElementType DeleteCircularLinkList(CircularLinkList * clList, int pos) {
  59. ElementType element;
  60. element.id = -999;
  61. if (pos == 1) {
  62. CircularNode * node = clList -> next;
  63. if (node) {
  64. element = node -> data;
  65. CircularNode * lastNode = clList -> next;
  66. for (int i = 1; i < clList -> length; ++i) {
  67. lastNode = lastNode -> next;
  68. }
  69. clList -> next = node -> next;
  70. lastNode -> next = clList -> next;
  71. free(node);
  72. clList -> length--;
  73. }
  74. return element;
  75. }
  76. CircularNode * preNode;
  77. CircularNode * node = clList -> next;
  78. for (int i = 1; node && i < pos; ++i) {
  79. preNode = node;
  80. node = node -> next;
  81. }
  82. if (node) {
  83. element = node -> data;
  84. preNode -> next = node -> next;
  85. free(node);
  86. clList -> length--;
  87. }
  88. return element;
  89. };
  1. // main.c
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include "DataElement.h"
  6. #include "CircularLinkList.h"
  7. ElementType dataArray[] = {
  8. {1, "奇异博士"},
  9. {2, "美国队长"},
  10. {3, "太上老君"},
  11. {4, "齐天大圣"},
  12. };
  13. void TestCircularLinkList();
  14. int main() {
  15. TestCircularLinkList();
  16. return 0;
  17. }
  18. void TestCircularLinkList() {
  19. CircularLinkList * clList = (CircularLinkList *)malloc(sizeof(CircularLinkList));
  20. clList -> length = 0;
  21. clList -> next = NULL;
  22. InitCircularLinkList(clList, dataArray, 4);
  23. PrintCircularLinkList(clList);
  24. ElementType element = DeleteCircularLinkList(clList, 2);
  25. printf("删除的元素:%s\n", element.name);
  26. printf("删除后的链表!\n");
  27. PrintCircularLinkList(clList);
  28. };

循环双链表

当循环双链表为空表时,其头节点的prior域和next域都为等于L