• 数据结构之循环链表(C语言)


    循环链表概念:

           循环链表是一种特殊的链表结构。它与普通链表不同的地方在于,最后一个节点指向第一个节点,形成了一个环。这也就意味着,在循环链表中,每个节点都有前驱节点和后继节点。循环链表既可以向前遍历,也可以向后遍历。循环链表的应用场景主要是在需要循环处理数据的场合,例如游戏中的玩家列表、环形缓存等。

    循环单链表的操作

    基本代码:

    1. struct Node {
    2. int data;
    3. struct Node* next;
    4. };
    5. struct Node* head = NULL;//头指针
    6. int count = 0; //统计节点数量
    7. struct Node* new(int x) //新节点的建立
    8. {
    9. struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
    10. temp->data = x;
    11. temp->next = NULL;
    12. return temp;
    13. }


    1、循环单链表的建立

    头插法

    1. void headList(int x)
    2. {
    3. struct Node* temp = new(x);
    4. struct Node* header = head; //用header来代替头指针来遍历
    5. if (head == NULL) //链表为空
    6. {
    7. head = temp;
    8. temp->next = head;
    9. count++;
    10. return;
    11. }
    12. temp->next = head; //新节点指向head
    13. while (header->next != temp->next) //header移动到最后的节点
    14. header = header->next;
    15. header->next = temp; //header指向开头
    16. head = temp; //头指针更新
    17. count++;
    18. }

    尾插法

    1. void lastList(int x)
    2. {
    3. struct Node* temp = new(x);
    4. struct Node* header = head;
    5. if (head == NULL)
    6. {
    7. head = temp;
    8. temp->next = head;
    9. count++;
    10. return;
    11. }
    12. while (header->next != head) //header移动到尾节点
    13. header = header->next;
    14. temp->next = header->next; //新节点指向头指针
    15. header->next = temp; //header指向新节点
    16. count++;
    17. }

    2、链表的按位插入

    插入时应注意插入位置为开头或结尾,应进行特殊处理。

    1. void Insert(int x, int data)
    2. {
    3. struct Node* temp = new(data);
    4. struct Node* header = head;
    5. if (x == 1) //插入位置为1
    6. {
    7. temp->next = head;
    8. while (header->next != temp->next) //header移动到最后节点
    9. header = header->next;
    10. header->next = temp; //header指向新节点
    11. head = temp; //head更新
    12. count++;
    13. return;
    14. }
    15. if (x == count) //插入位置为count
    16. {
    17. while(header->next != head) //移动到最后节点
    18. header = header->next;
    19. temp->next = header->next; //新节点指向开头
    20. header->next = temp; //header指向新节点
    21. count++;
    22. return;
    23. }
    24. if (x<1 || x>count) //判断插入位置是否非法
    25. {
    26. printf("error!");
    27. return;
    28. }
    29. for (int i = 1; i < x-1; i++) //header移动到插入位置前节点
    30. header = header->next;
    31. temp->next = header->next; //新节点指向header指向的节点
    32. header->next = temp; //header指向新节点
    33. count++;
    34. }

    3、按位删除

    注意删除节点位置为1时,应特殊处理;

    1. void delete(int x)
    2. {
    3. struct Node* header = head;
    4. if (x<1 || x>count) //判断删除位置是否合法
    5. {
    6. printf("error!\n");
    7. return;
    8. }
    9. if (head == NULL) //链表为空
    10. {
    11. printf("empty!\n");
    12. return;
    13. }
    14. if (x == 1) //删除节点位置为开头
    15. {
    16. while (header->next != head) //header移动到最后节点
    17. header = header->next;
    18. struct Node* A = head; //保存head节点
    19. head = head->next; //head移动
    20. printf("delete a number is %d\n", A->data); //打印
    21. header->next = head; //将header指向新的head
    22. free(A); //释放内存
    23. count--; //数量-1
    24. return;
    25. }
    26. for (int i = 1; i < x - 1; i++) //header移动到删除位置前节点
    27. header = header->next;
    28. struct Node* A = header->next; //保存删除节点地址
    29. header->next = A->next; // header指向删除节点的后节点
    30. printf("delete a number is %d\n", A->data);
    31. free(A);
    32. count--;
    33. }

    完整代码:
     

    1. struct Node {
    2. int data;
    3. struct Node* next;
    4. };
    5. struct Node* head = NULL;//头指针
    6. int count = 0; //统计节点数量
    7. struct Node* new(int x) //新节点的建立
    8. {
    9. struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
    10. temp->data = x;
    11. temp->next = NULL;
    12. return temp;
    13. }
    14. //头插法
    15. void headList(int x)
    16. {
    17. struct Node* temp = new(x);
    18. struct Node* header = head; //用header来代替头指针来遍历
    19. if (head == NULL)
    20. {
    21. head = temp;
    22. temp->next = head;
    23. count++;
    24. return;
    25. }
    26. temp->next = head; //新节点指向head
    27. while (header->next != temp->next) //header移动到最后的节点
    28. header = header->next;
    29. header->next = temp; //header指向开头
    30. head = temp; //头指针更新
    31. count++;
    32. }
    33. //尾插法
    34. void lastList(int x)
    35. {
    36. struct Node* temp = new(x);
    37. struct Node* header = head;
    38. if (head == NULL)
    39. {
    40. head = temp;
    41. temp->next = head;
    42. count++;
    43. return;
    44. }
    45. while (header->next != head) //header移动到尾节点
    46. header = header->next;
    47. temp->next = header->next; //新节点指向头指针
    48. header->next = temp; //header指向新节点
    49. count++;
    50. }
    51. //按位插入
    52. void Insert(int x, int data)
    53. {
    54. struct Node* temp = new(data);
    55. struct Node* header = head;
    56. if (x == 1) //插入位置为1
    57. {
    58. temp->next = head;
    59. while (header->next != temp->next) //header移动到最后节点
    60. header = header->next;
    61. header->next = temp; //header指向新节点
    62. head = temp; //head更新
    63. count++;
    64. return;
    65. }
    66. if (x == count) //插入位置为count
    67. {
    68. while(header->next != head) //移动到最后节点
    69. header = header->next;
    70. temp->next = header->next; //新节点指向开头
    71. header->next = temp; //header指向新节点
    72. count++;
    73. return;
    74. }
    75. if (x<1 || x>count) //判断插入位置是否非法
    76. {
    77. printf("error!");
    78. return;
    79. }
    80. for (int i = 1; i < x-1; i++) //header移动到插入位置前节点
    81. header = header->next;
    82. temp->next = header->next; //新节点指向header指向的节点
    83. header->next = temp; //header指向新节点
    84. count++;
    85. }
    86. //删除
    87. void delete(int x)
    88. {
    89. struct Node* header = head;
    90. if (x<1 || x>count) //判断删除位置是否合法
    91. {
    92. printf("error!\n");
    93. return;
    94. }
    95. if (head == NULL) //链表为空
    96. {
    97. printf("empty!\n");
    98. return;
    99. }
    100. if (x == 1) //删除节点位置为开头
    101. {
    102. while (header->next != head) //header移动到最后节点
    103. header = header->next;
    104. struct Node* A = head; //保存head节点
    105. head = head->next; //head移动
    106. printf("delete a number is %d\n", A->data); //打印
    107. header->next = head; //将header指向新的head
    108. free(A); //释放内存
    109. count--; //数量-1
    110. return;
    111. }
    112. for (int i = 1; i < x - 1; i++) //header移动到删除位置前节点
    113. header = header->next;
    114. struct Node* A = header->next; //保存删除节点地址
    115. header->next = A->next; // header指向删除节点的后节点
    116. printf("delete a number is %d\n", A->data);
    117. free(A);
    118. count--;
    119. }
    120. void Print()
    121. {
    122. struct Node* header = head;
    123. for (int i = 0; i < 5; i++)
    124. {
    125. printf("%d ", header->data);
    126. header = header->next;
    127. }
    128. printf("\n");
    129. }
    130. int main()
    131. {
    132. lastList(3);
    133. lastList(5);
    134. lastList(2);
    135. lastList(4);
    136. Insert(1,8);
    137. Print();
    138. delete(1);
    139. Print();
    140. return 0;
    141. }

    循环双链表的操作

    基本代码:

    1. struct Node {
    2. int data;
    3. struct Node* left;
    4. struct Node* right;
    5. };
    6. struct Node* head = NULL;
    7. int count = 0;
    8. struct Node* new(int x)
    9. {
    10. struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
    11. temp->data = x;
    12. temp->left = NULL;
    13. temp->right = NULL;
    14. return temp;
    15. }

    1、循环双链表的建立

    头插法

    1. void headList(int x)
    2. {
    3. struct Node* temp = new(x);
    4. struct Node* header = head;
    5. if (head == NULL) //链表为空
    6. {
    7. head = temp;
    8. temp->right = head; //指向新节点
    9. temp->left = head; //指向新节点
    10. count++;
    11. return;
    12. }
    13. while (header->right != head) //header指向最后节点
    14. header = header->right;
    15. temp->right = head; //新节点右指针指向head
    16. head->left = temp; //head指向节点的左节点指向新节点
    17. temp->left = header; //新节点左指针指向header
    18. header->right = temp; //header右指针指向新节点
    19. head = temp; //头指针更新
    20. count++;
    21. }

    尾插法

    1. void lastList(int x)
    2. {
    3. struct Node* header = head;
    4. struct Node* temp = new(x);
    5. if (head == NULL)
    6. {
    7. head = temp;
    8. temp->right = head;
    9. temp->left = temp;
    10. count++;
    11. return;
    12. }
    13. while (header->right != head) //header指向尾节点
    14. header = header->right;
    15. temp->right = header->right; //新节点右指针指向head
    16. head->left = temp; //head的左指针指向新节点
    17. header->right = temp; //header的右指针指向新节点
    18. temp->left = header; //新节点的左指针指向header
    19. count++;
    20. }

    2、按位插入

    应对插入位置为1的情况进行特殊处理;

    1. void Insert(int x, int data)
    2. {
    3. struct Node* header = head;
    4. struct Node* temp = new(data);
    5. if (head == NULL)
    6. {
    7. printf("error!/n");
    8. return;
    9. }
    10. if (x<1 || x>count)
    11. {
    12. printf("error!\n");
    13. return;
    14. }
    15. if (x == 1) //插入位置为开头
    16. {
    17. while (header->right != head) //移动到尾节点
    18. header = header->right;
    19. temp->right = head; //新节点的右指针指向头节点
    20. header->right = temp; //header的右指针指向新节点
    21. temp->left = header; //新节点的左指针指向尾节点
    22. head->left = temp; //头节点的左指针指向新节点
    23. head = temp; //头指针的更新
    24. count++;
    25. return;
    26. }
    27. for (int i = 1; i <= x - 1; i++)
    28. header = header->right;
    29. temp->right = header->right;
    30. header->right->left = temp;
    31. header->right = temp;
    32. temp->left = header;
    33. count++;
    34. }

    3、按位删除

    对删除位置为开头和删除位置为结尾的情况进行特殊处理;

    1. void delete(int x)
    2. {
    3. struct Node* header = head;
    4. if (x<1 || x>count)
    5. {
    6. printf("error!\n");
    7. return;
    8. }
    9. if (x == 1)
    10. {
    11. struct Node* A = head;
    12. head = head->right;
    13. head->left = A->left;
    14. A->left->right = head;
    15. free(A);
    16. count--;
    17. return;
    18. }
    19. if (x == count)
    20. {
    21. struct Node* A = head->left;
    22. header = A->left;
    23. header->right = head;
    24. head->left = header;
    25. free(A);
    26. count--;
    27. return;
    28. }
    29. for (int i = 1; i < x - 1; i++)
    30. header = header->right;
    31. struct Node* A = header->right;
    32. header->right = A->right;
    33. A->right->left = header;
    34. free(A);
    35. count--;
    36. }

    4、遍历(打印)

    1. void Print()
    2. {
    3. int falg = 0;
    4. struct Node* header = head;
    5. while (header != head || falg == 0)
    6. {
    7. printf("%d ", header->data);
    8. if (header->right == head)
    9. {
    10. falg = 1;
    11. break;
    12. }
    13. header = header->right;
    14. }
    15. printf("\n");
    16. struct Node* last = header;
    17. while (header != last|| falg == 1)
    18. {
    19. printf("%d ", header->data);
    20. if (header->left == last)
    21. {
    22. falg = 0;
    23. break;
    24. }
    25. header = header->left;
    26. }
    27. printf("\n");
    28. }

    完整代码:

    1. struct Node {
    2. int data;
    3. struct Node* left;
    4. struct Node* right;
    5. };
    6. struct Node* head = NULL;
    7. int count = 0;
    8. struct Node* new(int x)
    9. {
    10. struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
    11. temp->data = x;
    12. temp->left = NULL;
    13. temp->right = NULL;
    14. return temp;
    15. }
    16. //头插法
    17. void headList(int x)
    18. {
    19. struct Node* temp = new(x);
    20. struct Node* header = head;
    21. if (head == NULL) //链表为空
    22. {
    23. head = temp;
    24. temp->right = head; //指向新节点
    25. temp->left = head; //指向新节点
    26. count++;
    27. return;
    28. }
    29. while (header->right != head) //header指向最后节点
    30. header = header->right;
    31. temp->right = head; //新节点右指针指向head
    32. head->left = temp; //head指向节点的左节点指向新节点
    33. temp->left = header; //新节点左指针指向header
    34. header->right = temp; //header右指针指向新节点
    35. head = temp; //头指针更新
    36. count++;
    37. }
    38. //尾插法
    39. void lastList(int x)
    40. {
    41. struct Node* header = head;
    42. struct Node* temp = new(x);
    43. if (head == NULL)
    44. {
    45. head = temp;
    46. temp->right = head;
    47. temp->left = temp;
    48. count++;
    49. return;
    50. }
    51. while (header->right != head) //header指向尾节点
    52. header = header->right;
    53. temp->right = header->right; //新节点右指针指向head
    54. head->left = temp; //head的左指针指向新节点
    55. header->right = temp; //header的右指针指向新节点
    56. temp->left = header; //新节点的左指针指向header
    57. count++;
    58. }
    59. //按位插入
    60. void Insert(int x, int data)
    61. {
    62. struct Node* header = head;
    63. struct Node* temp = new(data);
    64. if (head == NULL)
    65. {
    66. printf("error!/n");
    67. return;
    68. }
    69. if (x<1 || x>count)
    70. {
    71. printf("error!\n");
    72. return;
    73. }
    74. if (x == 1) //插入位置为开头
    75. {
    76. while (header->right != head) //移动到尾节点
    77. header = header->right;
    78. temp->right = head; //新节点的右指针指向头节点
    79. header->right = temp; //header的右指针指向新节点
    80. temp->left = header; //新节点的左指针指向尾节点
    81. head->left = temp; //头节点的左指针指向新节点
    82. head = temp; //头指针的更新
    83. count++;
    84. return;
    85. }
    86. for (int i = 1; i <= x - 1; i++)
    87. header = header->right;
    88. temp->right = header->right;
    89. header->right->left = temp;
    90. header->right = temp;
    91. temp->left = header;
    92. count++;
    93. }
    94. //删除
    95. void delete(int x)
    96. {
    97. struct Node* header = head;
    98. if (x<1 || x>count)
    99. {
    100. printf("error!\n");
    101. return;
    102. }
    103. if (x == 1)
    104. {
    105. struct Node* A = head;
    106. head = head->right;
    107. head->left = A->left;
    108. A->left->right = head;
    109. free(A);
    110. count--;
    111. return;
    112. }
    113. if (x == count)
    114. {
    115. struct Node* A = head->left;
    116. header = A->left;
    117. header->right = head;
    118. head->left = header;
    119. free(A);
    120. count--;
    121. return;
    122. }
    123. for (int i = 1; i < x - 1; i++)
    124. header = header->right;
    125. struct Node* A = header->right;
    126. header->right = A->right;
    127. A->right->left = header;
    128. free(A);
    129. count--;
    130. }
    131. //打印
    132. void Print()
    133. {
    134. int falg = 0;
    135. struct Node* header = head;
    136. while (header != head || falg == 0)
    137. {
    138. printf("%d ", header->data);
    139. if (header->right == head)
    140. {
    141. falg = 1;
    142. break;
    143. }
    144. header = header->right;
    145. }
    146. printf("\n");
    147. struct Node* last = header;
    148. while (header != last|| falg == 1)
    149. {
    150. printf("%d ", header->data);
    151. if (header->left == last)
    152. {
    153. falg = 0;
    154. break;
    155. }
    156. header = header->left;
    157. }
    158. printf("\n");
    159. }
    160. int main()
    161. {
    162. lastList(3);
    163. lastList(5);
    164. lastList(8);
    165. lastList(9);
    166. lastList(4);
    167. Print();
    168. Insert(1, 88);
    169. Insert(6, 99);
    170. Print();
    171. delete(5);
    172. Print();
    173. return 0;
    174. }

    链表章节完结!

  • 相关阅读:
    webpack优化系列三:vue子目录路径更改---publicPath
    人工智能行业源代码防数据防泄密需求分析
    使用群晖实现Videostation电影的大容量存储及分享教程
    什么是智慧型人格?智慧型性格的优缺点和职业规划
    Python程序流程控制结构
    sass安装步骤、概述、基本语法等
    C语言练习之消失的数字(两种解法)
    [SDN]Mininet中的miniedit问题汇总
    23种设计模式之代理模式(动态代理)
    游戏陪玩小程序怎么开发-游戏陪玩小程序功能
  • 原文地址:https://blog.csdn.net/sskdspdl/article/details/132652155