• C语言实现双向循环链表


    1. #include
    2. #include
    3. // 双向循环链表
    4. typedef int datatype_t;
    5. typedef struct node{
    6. datatype_t data;
    7. struct node *prior;
    8. struct node *next;
    9. } dlinklist_t;
    10. // 创建空的双向循环链表
    11. dlinklist_t * dlinklist_create() {
    12. dlinklist_t *dl;
    13. dl = (dlinklist_t *)malloc(sizeof(dlinklist_t));// malloc是从堆里面获得的空间
    14. dl->next = dl->prior = dl;
    15. return dl;
    16. }
    17. // 使用头插法向链表中插入数据
    18. void dlinklist_head_insert(dlinklist_t *dl, datatype_t value) {
    19. dlinklist_t *temp = (dlinklist_t *)malloc(sizeof(dlinklist_t));
    20. temp->data = value;
    21. // 这样写可以同时兼容头结点有数据和没有数据的情况
    22. dlinklist_t *pnext = dl->next;
    23. dl->next = temp;
    24. temp->next = pnext;
    25. pnext->prior = temp;
    26. return;
    27. }
    28. // 实现尾插法 双向循环链表的尾插是非常快的 因为可以直接得到需要的位置 时间复杂度为O(1)
    29. void dlinklist_tail_insert(dlinklist_t *dl, datatype_t value) {
    30. dlinklist_t *temp = (dlinklist_t *)malloc(sizeof(dlinklist_t));
    31. temp->data = value;
    32. temp->next = dl;
    33. temp->prior = dl->prior;
    34. dl->prior->next = temp;
    35. dl->prior = temp;
    36. return;
    37. }
    38. // 显示
    39. void dlinklist_show(dlinklist_t *dl) {
    40. dlinklist_t *temp = dl;
    41. while (dl->next != temp)
    42. {
    43. dl = dl->next;
    44. printf("%d ", dl->data);
    45. }
    46. printf("\n");
    47. return;
    48. }
    49. // 判断链表是否为空
    50. int dlinklist_empty(dlinklist_t *dl) {
    51. return dl->next == dl ? 1 : 0;
    52. }
    53. // 删除数据节点
    54. int dlinklist_head_delete(dlinklist_t *dl) {
    55. // 删除前先判断是否为空
    56. if (dlinklist_empty(dl))
    57. {
    58. printf("empty");
    59. return 0;
    60. }
    61. // 保存被删除节点的地址
    62. dlinklist_t *temp = dl->next;
    63. // 保存被删除节点的下一个节点的地址
    64. dlinklist_t *nnext = temp->next;
    65. // 将节点从双向循环链表中删除
    66. dl->next = nnext;
    67. nnext->prior = dl;
    68. // 保存数据并返回
    69. datatype_t value = temp->data;
    70. // 释放被删除节点占用的内存空间
    71. free(temp);
    72. temp = NULL;
    73. return value;
    74. }
    75. int main() {
    76. dlinklist_t *dl;
    77. dl = dlinklist_create();
    78. dlinklist_head_insert(dl, 100);
    79. dlinklist_head_insert(dl, 200);
    80. dlinklist_head_insert(dl, 300);
    81. dlinklist_show(dl);
    82. dlinklist_tail_insert(dl, 400);
    83. dlinklist_show(dl);
    84. printf("\n从节点中删除了:%d\n", dlinklist_head_delete(dl));
    85. dlinklist_show(dl);
    86. printf("\n从节点中删除了:%d\n", dlinklist_head_delete(dl));
    87. dlinklist_show(dl);
    88. printf("\n从节点中删除了:%d\n", dlinklist_head_delete(dl));
    89. dlinklist_show(dl);
    90. dlinklist_tail_insert(dl, 500);
    91. dlinklist_tail_insert(dl, 600);
    92. dlinklist_show(dl);
    93. printf("\n从节点中删除了:%d\n", dlinklist_head_delete(dl));
    94. dlinklist_show(dl);
    95. return 0;
    96. }

    下面是执行效果

     

  • 相关阅读:
    自己搜的算法题2.0
    Ubuntu磁盘扩展容量
    【SemiDrive源码分析】【X9芯片启动流程】33 - Display模块 相关概念解析
    关于Greenplum为什么基于PostgreSQL而不是MySQL?
    每日4道算法题——第002天
    数据分析—将txt文件转为csv文件;将csv文件转为xls文件
    [flume]组成|source|channel|事务|拦截器|选择器|处理器|监控器|数据丢失问题|如何保证数据的完整性
    SpringBoot自动配置工作流程中变更自动配置
    Posix与System V IPC
    Docker Compose详细教程(从入门到放弃)
  • 原文地址:https://blog.csdn.net/qq_35061546/article/details/127695220