链表

题单介绍

平时我们在定义多个变量时一般使用数组。 数组有个很大的优点,那就是想要取第几个变量就能取到第几个变量。 但是数组也有一个缺点,那就是在数组中间插入或者删除一个变量时,要把后面的所有变量都往后或往前挪一位,才能插入或者删除。 那么这个挪移的时间就会很慢,数组有多长,就可能要移多少个变量。 那么有没有方法能使插入和删除变快呢? 在写语文作文时,写完后发现中间少了一个字。那应该怎么把字插入进去? 可以把要插入的字写到另外的地方,然后做个标记表示应该插入到哪里。 那么我们能不能在插入变量的时候把变量放到其他地方,再做个标记呢? 对于每个变量a[i],再用nxt[i]记录一下他的下一个数所在的位置。 也就是说,**对于每个数,记录它下一个数所在的位置。那么这种数据结构就叫做链表。** 一般来说,链表的一个整体会用一个结构体来表示 ```cpp struct node{ int value;//记录该节点的值 node* nxt;//记录下一个节点所在的地址 }; ``` 不过由于在竞赛中指针很少使用,所以一般nxt记录的是下一个点在数组里的位置,而不是在内存里的地址。 所以结构体定义稍微改一下: ```cpp struct node{ int v; int nxt; }; node a[100];//定义若干节点备用 int cnt;//记录已经数组里前面多少个节点已经被使用了 int head;//记录这个链表的第一个元素所在的位置 遍历整个链表: for(int i=head;i!=0;i=a[i].nxt){//0表示链表结束 //语句 } 插入节点: void insert(int x,int y){//在第x个节点后面插入一个值y cnt++; a[cnt]=y; a[cnt].nxt=a[x].nxt; a[x].nxt=cnt; } 删除节点: void del(int x){//删除第x个节点后面的节点 a[x].nxt=a[a[x].nxt].nxt; } ``` 上面这段代码就是单链表的插入、删除和遍历了。 除了只能从前往后遍历的单链表,还有双向链表和循环链表。 双向链表指的是每个节点不仅记录下一个节点的位置,还记录上一个节点的位置。 循环链表指的是链表的尾部不会指向0,而是指向链表的第一个元素。 这两种链表对应的插入、删除和遍历代码都需要相应的修改。具体如何修改可以自行尝试。

题目列表

  • 约瑟夫问题
  • 队列安排