• 【数据结构】单链表


    • 链式存储定义

    为了表示每个数据元素与其直接后继元素之间的逻辑关系,每个元素除了存储本身的信息外,还需要存储指示其直接后继的信息(地址

    • 单链表
    1. 线性表的链式存储结构中,每个结点中只包含一个指针域,这样的链表叫单链表
    2. 通过每个结点的指针域将线性表的数据元素按照其逻辑次序链接在一起

    • 单链表的插入操作

     操作步骤:

    1. 找到插入位置的前一个结点(pCurrent
    2. 将新结点指针域(NewNode->next)指向 pCurrent->next 
    3. 将 pCurrent 的指针域(pCurrent->next)指向新结点(NewNode
    • 为什么不先链接 pCurrent 和 NewNode ?

    因为链表是通过指针去访问下一个数据元素的,pCurrent->next = NewNode 导致本来能找到下一个元素的指针被覆盖

    如果先链接 pCurrent 和 NewNode ,则新结点的指针域指向就会出现问题,无法链接链表后面的内容。

    • 单链表删除操作

    操作步骤

    1. 找到要被删除结点的前一个结点(pCurrent
    2. 创建新结点 DelNode 存储 pCurrent 结点的下一个位置(pCurrent->next),也就是需要删除的结点
    3. 将 pCurrent 的指针域(pCurrent->next)指向 需要删除结点的下一个位置(DelNode->next
    4. 释放需要删除的结点空间 

    C 语 言 实 现 单 链 表

    • 链表框架
    1. // 链表结点
    2. typedef struct LINKNODE{
    3. void* data; // 无类型指针,可以指向任何数据类型
    4. struct LINKNODE* next; // 结点指针域
    5. }LinkNode;
    6. // 链表结构体
    7. typedef struct LINKLIST {
    8. LinkNode* head; // 头结点
    9. int size; // 链表长
    10. }LinkList;
    11. // 打印函数指针
    12. typedef void(*PRINTLINKNODE)(void*);
    13. // 初始化链表
    14. LinkList* Init_LinkList();
    15. // 指定位置插入数据
    16. void Insert_LinkList(LinkList* list, int pos, void* data);
    17. // 删除指定位置的值
    18. void RemoveByPos_LinkList(LinkList* list, int pos);
    19. // 获取链表的长度
    20. int Size_LinkList(LinkList* list);
    21. // 按照 数据 查找
    22. int Find_LinkList(LinkList* list, void* data);
    23. // 返回第一个结点
    24. void* Front_LintList(LinkList* list);
    25. // 打印
    26. void Print_LinkList(LinkList* list, PRINTLINKNODE print);
    27. // 释放链表内存
    28. void FreeSpace_LinkList(LinkList* list);
    • 链表实现
    1. // 初始化链表
    2. LinkList* Init_LinkList(){
    3. LinkList* list = (LinkList*)malloc(sizeof(LinkList));
    4. list->size = 0;
    5. // 头结点 (不保存数据) (为了方便插入)
    6. list->head = (LinkNode*)malloc(sizeof(LinkNode));
    7. list->head->data = NULL;
    8. list->head->next = NULL;
    9. return list;
    10. }
    11. // 指定位置插入数据
    12. void Insert_LinkList(LinkList* list, int pos, void* data){
    13. if (list == NULL) return;
    14. if (data == NULL) return;
    15. // 友好处理,pos 越界
    16. if (pos < 0 || pos > list->size) {
    17. pos = list->size;
    18. }
    19. // 创建新的结点
    20. LinkNode* NewNode = (LinkNode*)malloc(sizeof(LinkNode));
    21. NewNode->next = NULL;
    22. NewNode->data = data;
    23. // 插入结点 pos = 2,就要找 1 这个位置
    24. // 找结点
    25. // 辅助指针变量
    26. LinkNode* pCurrent = list->head;
    27. for (int i = 0; i < pos; i++) {
    28. pCurrent = pCurrent->next;
    29. } // 找到
    30. // 新结点插入链表
    31. NewNode->next = pCurrent->next;
    32. pCurrent->next = NewNode;
    33. // 更新长度
    34. list->size++;
    35. }
    36. // 删除指定位置的值
    37. void RemoveByPos_LinkList(LinkList* list, int pos){
    38. if (list == NULL) return;
    39. if (pos < 0 || pos > list->size) return;
    40. // pos 2 , 找到前一个结点
    41. LinkNode* pCurrent = list->head;
    42. // 查找删除结点的前一个结点
    43. for (int i = 0; i < pos; i++) {
    44. pCurrent = pCurrent->next;
    45. }
    46. LinkNode* DelNode = pCurrent->next;
    47. pCurrent->next = DelNode->next;
    48. // 释放删除节点
    49. free(DelNode);
    50. DelNode = NULL;
    51. // 更新长度
    52. list->size--;
    53. }
    54. // 获取链表的长度
    55. int Size_LinkList(LinkList* list){
    56. return list->size;
    57. }
    58. // 查找
    59. int Find_LinkList(LinkList* list, void* data){
    60. int pos = -1;
    61. if (list == NULL) return pos;
    62. if (data == NULL) return pos;
    63. LinkNode* pCurrent = list->head->next;
    64. while (pCurrent != NULL) {
    65. if (pCurrent->data == data) {
    66. break;
    67. }
    68. pos++;
    69. pCurrent = pCurrent->next;
    70. }
    71. return pos;
    72. }
    73. // 返回第一个结点
    74. void* Front_LintList(LinkList* list){
    75. return list->head->next->data; // 返回数据域
    76. }
    77. // 打印
    78. void Print_LinkList(LinkList* list, PRINTLINKNODE print){
    79. if (list == NULL) return;
    80. LinkNode* pCurrent = list->head->next;
    81. while (pCurrent != NULL) {
    82. print(pCurrent->data);
    83. pCurrent = pCurrent->next;
    84. }
    85. }
    86. // 释放链表内存
    87. void FreeSpace_LinkList(LinkList* list){
    88. if (list == NULL) return;
    89. // 辅助结点
    90. LinkNode* pCurrent = list->head;
    91. while (pCurrent != NULL) {
    92. // 缓存下一个结点
    93. LinkNode* pNext = pCurrent->next;
    94. free(pCurrent);
    95. pCurrent = pNext;
    96. }
    97. // 释放链表内存
    98. free(list);
    99. }

    测试代码:

    1. void test() {
    2. LinkList* list;
    3. list = Init_LinkList();
    4. Person p1 = { "aaa", 19, 99 };
    5. Person p2 = { "bbb", 20, 98 };
    6. Person p3 = { "ccc", 21, 97 };
    7. Person p4 = { "ddd", 22, 96 };
    8. Person p5 = { "eee", 23, 95 };
    9. // 插入链表
    10. Insert_LinkList(list, 0, &p1);
    11. Insert_LinkList(list, 0, &p2);
    12. Insert_LinkList(list, 0, &p3);
    13. Insert_LinkList(list, 0, &p4);
    14. Insert_LinkList(list, 0, &p5); // pos = 0 头插效果
    15. // 打印
    16. Print_LinkList(list, MyPrint);
    17. // 获取长度
    18. printf("单链表当前长度为: %d\n", Size_LinkList(list)); // 5
    19. printf("-----------------------\n");
    20. // 删除
    21. RemoveByPos_LinkList(list, 1);
    22. // 打印
    23. Print_LinkList(list, MyPrint); // ddd 被删
    24. // 获取长度
    25. printf("单链表当前长度为: %d\n", Size_LinkList(list)); // 4
    26. // 查找
    27. Person find_p = { "aaa", 19, 99 };
    28. int pos = Find_LinkList(list, &find_p);
    29. printf("find_p位置: %d\n", pos); // 3
    30. // 返回第一个结点数据,强制转换成 Person*,结点类型 Person
    31. printf("返回第一个结点数据\n");
    32. Person* FirstNode = (Person*)Front_LintList(list);
    33. printf("name: %s age: %d score: %d\n", FirstNode->name, FirstNode->age, FirstNode->score);
    34. // 销毁
    35. FreeSpace_LinkList(list);
    36. }

    运行结果:

  • 相关阅读:
    【threejs教程8】threejs添加3D场景键盘控制
    JDBC快速入门和获取数据库的连接方式
    模拟实现stl库中的list(支持const迭代器、移动语义)
    [NPUCTF2020]ezinclude
    【机试题】LazyIterator迭代器懒加载问题
    Docker 中 jdk8容器里无法使用 JDK 的 jmap 等命令的问题
    Python数据结构——树
    MySQL的常用聚合函数
    SAP SD模块前台操作
    YOLO V2详解
  • 原文地址:https://blog.csdn.net/xuan3215/article/details/126309975