1. 链表基本概念

1.1 链表

image.png

  1. 链表是一种常用的数据结构,它通过指针将一些列数据结点,连接成一个数据链。相对于数组,链表具有更好的动态性(非顺序存储)。
  2. 数据域用来存储数据,指针域用于建立与下一个结点的联系。
  3. 建立链表时无需预先知道数据总量的,可以随机的分配空间,可以高效的在链表中的任意位置实时插入或删除数据。
  4. 链表的开销,主要是访问顺序性和组织链的空间损失。

数组和链表的区别:
数组:一次性分配一块连续的存储区域。
优点:随机访问元素效率高
缺点:a. 需要分配一块连续的存储区域(很大区域,有可能分配失败)
b. 删除和插入某个元素效率低

链表:无需一次性分配一块连续的存储区域,只需分配n块节点存储区域,通过指针建立关系。
优点:a. 不需要一块连续的存储区域
b. 删除和插入某个元素效率高
缺点:随机访问元素效率低

1.2 链表节点

链表的节点类型实际上是结构体变量,此结构体包含数据域指针域

  1. 数据域用来存储数据;
  2. 指针域用于建立与下一个结点的联系,当此节点为尾节点时,指针域的值为NULL;
  1. typedef struct Node
  2. {
  3. //数据域
  4. int id;
  5. char name[50];
  6. //指针域
  7. struct Node *next;
  8. }Node;

image.png

1.3 链表的分类

链表分为:静态链表和动态链表
静态链表和动态链表是线性表链式存储结构的两种不同的表示方式:

  1. 所有结点都是在程序中定义的,不是临时开辟的,也不能用完后释放,这种链表称为“静态链表”。
  2. 所谓动态链表,是指在程序执行过程中从无到有地建立起一个链表,即一个一个地开辟结点和输入各结点数据,并建立起前后相链的关系。

1.3.1 静态链表

  1. typedef struct Stu
  2. {
  3. int id; //数据域
  4. char name[100];
  5. struct Stu *next; //指针域
  6. }Stu;
  7. void test()
  8. {
  9. //初始化三个结构体变量
  10. Stu s1 = { 1, "yuri", NULL };
  11. Stu s2 = { 2, "lily", NULL };
  12. Stu s3 = { 3, "lilei", NULL };
  13. s1.next = &s2; //s1的next指针指向s2
  14. s2.next = &s3;
  15. s3.next = NULL; //尾结点
  16. Stu *p = &s1;
  17. while (p != NULL)
  18. {
  19. printf("id = %d, name = %s\n", p->id, p->name);
  20. //结点往后移动一位
  21. p = p->next;
  22. }
  23. }

1.3.2 动态链表

  1. typedef struct Stu{
  2. int id; //数据域
  3. char name[100];
  4. struct Stu *next; //指针域
  5. }Stu;
  6. void test(){
  7. //动态分配3个节点
  8. Stu *s1 = (Stu *)malloc(sizeof(Stu));
  9. s1->id = 1;
  10. strcpy(s1->name, "yuri");
  11. Stu *s2 = (Stu *)malloc(sizeof(Stu));
  12. s2->id = 2;
  13. strcpy(s2->name, "lily");
  14. Stu *s3 = (Stu *)malloc(sizeof(Stu));
  15. s3->id = 3;
  16. strcpy(s3->name, "lilei");
  17. //建立节点的关系
  18. s1->next = s2; //s1的next指针指向s2
  19. s2->next = s3;
  20. s3->next = NULL; //尾结点
  21. //遍历节点
  22. Stu *p = s1;
  23. while (p != NULL)
  24. {
  25. printf("id = %d, name = %s\n", p->id, p->name);
  26. //结点往后移动一位
  27. p = p->next;
  28. }
  29. //释放节点空间
  30. p = s1;
  31. Stu *tmp = NULL;
  32. while (p != NULL)
  33. {
  34. tmp = p;
  35. p = p->next;
  36. free(tmp);
  37. tmp = NULL;
  38. }
  39. }