不采用动态链表
一般情况下,都是直接使用下面的代码进行模拟的
struct Node{
int val;
Node *next;
}
然后当我们需要进行创建一个新的节点时,都需要使用new Node()
,非常慢!!!
数据规模一般都是10w~100w+的数据,这样时间花费下来,就已经很久了
所以,在做题时,我们一般不采用
动态链表
方式!
采用数组模拟链表
完成链表问题的时候,可以尝试通过图形
来解决。
单链表
用得最多是:领接表——其实是n个链表(应用于:
存储树 和 图
)
一般是这样的,开始时头结点指向空
插入一些元素后
每个点都会存两个值
- 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
第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号点的后面
第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的下一个点