• 双向链表C语言版本


    1、声明链表节点操作函数 linklist.h

    1. #ifndef LINKLIST_H__
    2. #define LINKLIST_H__
    3. #include
    4. #include
    5. #include
    6. //#define TAIL_ADD
    7. #define HEAD_ADD
    8. typedef int LinkDataType;
    9. // 构造节点
    10. struct LinkNode
    11. {
    12. LinkDataType data;
    13. struct LinkNode* pre;
    14. struct LinkNode* next;
    15. };
    16. typedef struct LinkNode LinkNode;
    17. /**创建带头结点链表*/
    18. LinkNode* create_linklist();
    19. LinkNode* get_link_node(LinkNode* node);
    20. /**新增节点*/
    21. int insert_link_node(LinkNode* link,LinkDataType data);
    22. /**修改节点*/
    23. int update_link_node(LinkNode* link,LinkDataType data,int index);
    24. bool is_end(LinkNode* link,LinkNode* node);
    25. void show_link_node(LinkNode* node);
    26. /**节点查询*/
    27. int find_link_node(LinkNode* link,LinkDataType data);
    28. void show_link(LinkNode* link);
    29. /**链表销毁*/
    30. void destory_link(LinkNode* link);
    31. int* get_arr();
    32. #endif

    2、定函数实现linklist.c

    1. #include "linklist.h"
    2. LinkNode* create_linklist()
    3. {
    4. LinkNode* link = malloc(sizeof(LinkNode*));
    5. if(link == NULL)
    6. {
    7. perror("create_linklist fail");
    8. exit(0);
    9. }
    10. link->next = link;
    11. link->pre = link;
    12. link->data = 0;
    13. return link;
    14. }
    15. int insert_link_node(LinkNode* link,LinkDataType data)
    16. {
    17. LinkNode* node = malloc(sizeof(LinkNode*));
    18. if(node == NULL)
    19. {
    20. perror("node init fail");
    21. exit(0);
    22. }
    23. node->data = data;
    24. /// 头插法
    25. #ifdef HEAD_ADD
    26. node->pre = link;
    27. node->next = link->next;
    28. link->next->pre = node;
    29. link->next = node;
    30. #endif
    31. ///尾插法
    32. #ifdef TAIL_ADD
    33. node->next = link;
    34. node->pre = link->pre;
    35. link->pre->next = node;
    36. link->pre = node;
    37. #endif
    38. return 0;
    39. }
    40. LinkNode* get_link_node(LinkNode* node)
    41. {
    42. LinkNode* tmp = NULL;
    43. #ifdef HEAD_ADD
    44. tmp = node->next;
    45. #endif
    46. #ifdef TAIL_ADD
    47. tmp = node->pre;
    48. #endif
    49. return tmp;
    50. }
    51. bool is_end(LinkNode* link,LinkNode* node)
    52. {
    53. #ifdef HEAD_ADD
    54. return node->next==link->pre;
    55. #endif
    56. #ifdef TATL_ADD
    57. return node->pre==link->next
    58. #endif
    59. }
    60. int delete_link_node(LinkNode* link,LinkDataType data)
    61. {
    62. LinkNode* node = link;
    63. while (node)
    64. {
    65. if(node->data == data)
    66. {
    67. LinkNode* next_tmp = get_link_node(node);
    68. node->pre->next = node->next;
    69. node->next->pre = node->pre;
    70. free(node);
    71. node = next_tmp;
    72. }
    73. }
    74. return 0;
    75. }
    76. int update_link_node(LinkNode* link,LinkDataType data,int index)
    77. {
    78. int c = 0;
    79. LinkNode* node = link;
    80. while (node)
    81. {
    82. if(c == index)
    83. {
    84. node->data = data;
    85. return c;
    86. }
    87. node = get_link_node(node);
    88. if(is_end(link,node))
    89. break;
    90. }
    91. return -1;
    92. }
    93. int find_link_node(LinkNode* link,LinkDataType data)
    94. {
    95. int index =0;
    96. LinkNode* node = link;
    97. while (node)
    98. {
    99. if(node->data==data)
    100. {
    101. return index;
    102. }
    103. node = get_link_node(node);
    104. index++;
    105. if(is_end(link,node))
    106. break;
    107. }
    108. return -1;
    109. }
    110. void show_link_node(LinkNode* node)
    111. {
    112. int pre_data = 0;
    113. int next_data = 0;
    114. int data = node->data;
    115. if(node->pre!=NULL)
    116. {
    117. pre_data = node->pre->data;
    118. }
    119. if(node->next!=NULL)
    120. {
    121. next_data = node->next->data;
    122. }
    123. printf("%d, %d, %d \n",pre_data,data,next_data);
    124. }
    125. void show_link(LinkNode* link)
    126. {
    127. LinkNode* node = link;
    128. while (!is_end(link,node))
    129. {
    130. show_link_node(node);
    131. node = get_link_node(node);
    132. }
    133. }
    134. void destory_link(LinkNode* link)
    135. {
    136. LinkNode* node = link;
    137. while (node)
    138. {
    139. LinkNode* tmp = get_link_node(node);
    140. free(node);
    141. node = tmp;
    142. if(is_end(link,node))
    143. break;
    144. }
    145. }
    146. int* get_arr()
    147. {
    148. int len =10;
    149. int* arr = malloc(len*sizeof(int*));
    150. int i=0;
    151. for(;i
    152. {
    153. arr[i]=i;
    154. }
    155. return arr;
    156. }

    3、编写测试函数main.h  main.c

        main.h函数定义定义

    1. #ifndef MAIN_H__
    2. #define MAIN_H__
    3. #include "linklist.h"
    4. void test_double_link_list()
    5. {
    6. LinkNode* link = create_linklist();
    7. int* arr = get_arr();
    8. int i=0;
    9. for(;i<10;i++)
    10. {
    11. insert_link_node(link,*(arr+i));
    12. }
    13. show_link(link);
    14. free(link);
    15. free(arr);
    16. };
    17. #endif

     main.c调用测试

    1. #include "main.h"
    2. int main()
    3. {
    4. test_double_link_list();
    5. exit(0);
    6. }

    4、编写Makefile文件

    1. #$^ 表示所有的依赖文件
    2. #$@ 表示生成的目标文件
    3. #$< 代表第一个依赖文件
    4. #dapp: main.o
    5. # gcc main.o -o dsapp
    6. #main.o: main.c
    7. # gcc -c main.c -o main.o
    8. #SRCS += $(wildcard *.c)
    9. #INCS += $(wildcard *.h)
    10. BUILD_DIR = ./build
    11. TARGET_COMPILE += $(BUILD_DIR)/main.o $(BUILD_DIR)/linklist.o
    12. TARGET_EXE = dsapp.out
    13. all: msg $(TARGET_EXE) clean
    14. #输出环境变量
    15. msg:
    16. @echo $(CC) @echo $(RM)
    17. #生成可执行文件
    18. # 链接动态库要放在.o文件后面
    19. # $@ 取的是输入变量(即$(TARGET_COMPILE )所指向的main.o 、linklist.o等)
    20. # $^ 取得是输出目标(即$(TARGET_exe)所指向的 dsapp.out)
    21. $(TARGET_EXE): $(TARGET_COMPILE)
    22. $(CC) -Wall $^ -o $@
    23. #执行编译
    24. $(BUILD_DIR)/%.o: %.c
    25. $(CC) -Wall -c $^ -o $@
    26. #删除编译文件
    27. clean: $(TARGET_COMPILE)
    28. $(RM) $(TARGET_COMPILE)

  • 相关阅读:
    五分钟搭建博客系统 OK?
    Halo 开源项目学习(二):实体类与数据表
    Pro Git日常学习记录-Git基础-9.打标签
    压测工具Jmeter介绍及使用
    办公网络构建
    正则表达式基本语法
    VB6.0实现修改EXE程序的图标
    MySQL 锁常见知识点&面试题总结
    Puppeteer记录操作过程及优秀的开源插件(五)
    JAVA图书管理练习
  • 原文地址:https://blog.csdn.net/fengchengwu2012/article/details/133803628