数据结构--链表

打印 上一主题 下一主题

主题 893|帖子 893|积分 2679

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
相较于数组,链表有以下长处:
逻辑结构

(1)链表接纳动态内存分配的方式,在内存中不连续 (2)支持动态增长大概删除元素 (3)需要时可以使用malloc大概new来申请内存,不消时使用free大概delete来释放内存
内存结构

链表从堆上分配内存,自由度大,但是要注意内存泄漏
访问效率

链表访问效率低,如果想要访问某个元素,需要从头遍历
越界问题

指针一般使用$ malloc $关键字申请动态内存,只要可以申请得到链表空间,链表就无越界风险
链表的根本操作

创建链表

这里用结构体(struct)存储链表。不同于C++,C语言中新定义结构体变量需要以下格式
  1. struct Data a;
复制代码
使用typedef关键字后可直接用Sqlist来定义变量
next指针指向表中下一个数据
  1. typedef struct Data {
  2.         int value;
  3.         struct Data* next;
  4. }Sqlist;
复制代码
malloc 为库中的函数,用于动态分配内存,传入所需内存大小,返回值为范例为void的指针,这里使用(Sqlist *)逼迫转换
  1. Sqlist* Init()
  2. {
  3.         Sqlist* t = (Sqlist*)malloc(sizeof(Sqlist));
  4.         t->value = 1;
  5.         t->next = NULL;
  6.         return t;
  7. }
复制代码
在pos后插入数值

传入参数为插入数值的位置pos和数值,从头开始遍历链表直到第pos个位置,新建一个节点,将pos指向新节点,新节点指向pos的下一个节点(pos->next)
  1. Sqlist* Create_node()
  2. {
  3.         Sqlist* node = (Sqlist*)malloc(sizeof(Sqlist));;
  4.         return node;
  5. }
  6. Sqlist* getPos(Sqlist*head,int pos)
  7. {
  8.         Sqlist* t = head;
  9.         int i = 1;
  10.         while (i != pos && t != NULL)
  11.         {
  12.                 t = t->next; i++;
  13.         }
  14.         return t;
  15. }
  16. void Insert(Sqlist* head, int pos, int value)
  17. {
  18.         Sqlist* t = getPos(head,pos), * newNode = Create_node;
  19.         newNode->value = value;
  20.         t->next = newNode;
  21.         if (t == NULL)//t 为最后一个节点,没有next
  22.         {
  23.                 return;
  24.         }
  25.         newNode->next = t->next;
  26. }
复制代码
删除节点pos

记载下当前节点的前一个节点pre,将pre->next指向pos->next,释放pos的内存
  1. void Delete(Sqlist* head, int pos)
  2. {
  3.         Sqlist* t = head,*pre=head; int i = 1;
  4.         while (i != pos && t != NULL)
  5.         {
  6.                 pre = t;
  7.                 t = t->next;
  8.                 i++;
  9.         }
  10.         if (t != NULL)
  11.         {
  12.                 pre->next = t->next;
  13.                 free(t);
  14.         }
  15. }
复制代码
根本操作大概就这些,根据实际问题机动运用。
提供luogu上的一道练习题luogu
由于用指针维护链表每次操作都需要从头遍历,导致效率不尽人意,想要AC这道题可以考虑使用数组模仿链表
如果出现了RE,可能是调用了NULL->next
附70ptsCODE
  睁开查看
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. using namespace std;
  4. typedef struct data
  5. {
  6.         int value;
  7.         struct data* next;
  8. }Sqlist;
  9. int Length = 0;
  10. Sqlist* Create()
  11. {
  12.         Sqlist* node = (Sqlist*)malloc(sizeof(Sqlist));
  13.         Length++;
  14.         return node;
  15. }
  16. Sqlist* Init()
  17. {
  18.         Sqlist* head;
  19.         head = Create();
  20.         head->value = 1;
  21.         head->next = NULL;
  22.         return head;
  23. }
  24. void Delete(Sqlist* head, int ith)
  25. {
  26.         Sqlist* t = head, * pre=head;
  27.         int i = 1;
  28.         while (i != ith && t != NULL)
  29.         {
  30.                 pre = t;t = t->next; i++;
  31.         }
  32.         pre->next = t->next;
  33.         free(t); Length--;
  34. }
  35. void Insert(Sqlist* head, int ith, int data)
  36. {
  37.         Sqlist* t = head,*newnode = Create();
  38.         int i = 1;
  39.         while (i != ith && t != NULL)
  40.         {
  41.                 t = t->next; i++;
  42.         }
  43.         newnode->value = data;
  44.         newnode->next = t->next;
  45.         t->next = newnode;
  46. }
  47. int Locate(Sqlist* head, int Target)
  48. {
  49.         Sqlist* t = head; int pos=1;
  50.         while (t != NULL)
  51.         {
  52.                 if (t->value == Target)return pos;
  53.                 t = t->next; pos++;
  54.         }
  55.         return 0;
  56. }
  57. int Query(Sqlist* head, int pos)
  58. {
  59.         Sqlist* t = head;
  60.         int i = 1;
  61.         while (t != NULL && i != pos)
  62.         {
  63.                 t = t->next; i++;
  64.         }
  65.         return t->value;
  66. }
  67. void print(Sqlist* head)
  68. {
  69.         Sqlist* t = head;
  70.         while (t != NULL)
  71.         {
  72.                 printf("%d ", t->value);
  73.                 t = t->next;
  74.         }
  75.         puts("");
  76. }
  77. inline int read()
  78. {
  79.         char c = getchar(); int res = 0;
  80.         while (c < '0' || c>'9')c = getchar();
  81.         while (c >= '0' && c <= '9') {
  82.                 res = (res << 1) + (res << 3) + (c - '0'); c = getchar();
  83.         }
  84.         return res;
  85. }
  86. void work()
  87. {
  88.         int q = read();
  89.         Sqlist* L = Init();
  90.         for (int i = 1; i <= q; ++i)
  91.         {
  92.                 int var = read(),x,y;
  93.                 if (var == 1)
  94.                 {
  95.                         x = read(), y = read();
  96.                         int pos= Locate(L, x);
  97.                         Insert(L, pos, y);
  98.                 }
  99.                 if (var == 2)
  100.                 {
  101.                         x = read();
  102.                         int pos=Locate(L, x);
  103.                         if (pos == Length)printf("0\n");
  104.                         else {
  105.                                 printf("%d\n",Query(L,pos+1));
  106.                         }
  107.                 }
  108.                 if (var == 3)
  109.                 {
  110.                         x = read();
  111.                         int pos = Locate(L, x);
  112.                         Delete(L, pos+1);
  113.                 }
  114.         }
  115. }
  116. int main()
  117. {
  118.         work();
  119.         return 0;
  120. }
  121.   </stdlib.h></stdio.h>
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

石小疯

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表