不采用动态链表
一般情况下,都是直接使用下面的代码进行模拟的
struct Node{
int val;
Node *next;
}
然后当我们需要进行创建一个新的节点时,都需要使用new Node(),非常慢!!!
数据规模一般都是10w~100w+的数据,这样时间花费下来,就已经很久了
所以,在做题时,我们一般不采用
动态链表方式!
采用数组模拟链表
完成链表问题的时候,可以尝试通过图形来解决。
单链表
用得最多是:领接表——其实是n个链表(应用于:
存储树 和 图)
一般是这样的,开始时头结点指向空
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p2zPy9a8-1686269135297)(assets/image-20230521210317-k6tr956.png)]](https://img-blog.csdnimg.cn/ee11664c80834059ab18ba44d7ceef98.png)
插入一些元素后
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6f9DoMkH-1686269135298)(assets/image-20230521210333-1wr6pkv.png)]](https://img-blog.csdnimg.cn/1b9b2a88cf1d454480430635701b50f2.png)
每个点都会存两个值
- value——定义
value数组(e[N]) - next指针——定义(ne[N])
问题一:
e[N]和ne[N]是如何关联起来的呢?是通过!!!下标!!!
0号点的
值是:e[0]
next:ne[0] = 1(下一个点为 1 节点)
假设值分别为3 ,5,7,9
那么
- e[0] = 3,ne[0] = 1
- e[1] = 5 ,ne[1] = 2
- e[2] = 7 ,ne[1] = 3
- e[3] = 9 ,ne[1] = -1==(空集)==
初始化
int head , e[N] , ne[N] , idx;
head:头结点下标e[i]:第i个的值ne[i]:下一个(next)的值idx:当前使用的下标(要插入or删除的下标)
插入操作(头结点)
先将插入的点指向head->next,再将head->next指向x——否则会丢失head的next
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bYBy0Y9C-1686269135298)(assets/image-20230521211835-dgm3m53.png)]](https://img-blog.csdnimg.cn/28d59d68462c4c5d9025663652e3ed9d.png)
第0步:将x存入值
e[i] = x;
第一步:插入的点指向head->next
ne[idx] = head
因为这里
ne[i]代表的就是下一个指向的值
第二步:head指向插入的点
head = idx;
第三步:idx自增
idx ++;
当前指标已经使用过了,所以需要自增
int head_insert(int x){
e[idx] = x;
ne[idx] = head;
head = idx ++;
}
一般add操作
将x插入 下标是k 的点后面
例如,当前我们需要将红色的点,插入到2号点的后面
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jUTsnqXS-1686269135299)(assets/image-20230609072135-4civp21.png)]](https://img-blog.csdnimg.cn/b6c484036db24489ac4c6b091277b067.png)
第0步:将x存入值
e[i] = x;
第1步:红颜色的next指针指向2号点的下一个指针
ne[idx] = ne[k];
第2步:将2号点的下一个指向红色的点
ne[k] = idx;
第3步:idx自增
idx ++;
完整操作代码
void insert(int k , int x){
e[idx] = x;
ne[idx] = ne[k];
ne[k] = idx++;
}
删除操作
将下标k 后面的点删掉。
直接将1号点的指针指向3号点即可
ne[k] = ne[ne[k]];
遍历
for(int i = head ; i != -1 ; i = ne[i])
i = head:从头结点开始i != -1:head默认值为-1i = ne[i]:访问当前i的下一个点




















