为什么使用数组来模拟链表?
如果数据规模很大, 一个一个的new操作太慢了, 会超时, 使用数组会大大加快速度
解释 :
定义两个数组
数组e[i] 存放要存入的数值 相当于链表中节点的数据
数组ne[i] 存放下个节点的下标,指向下个节点
初始化设置head = -1;即头结点指向的下一个节点索引为-1,即为空,是一个空链表
idx = 0;用来表示要插入的数所在链表的位置,为0则表示没有存入数据
// 初始化数据
private static void init() {
head = -1; // 没有头结点
idx = 0; // 没有存入数据
}
插入一个数据到头结点:
private static void addToHead(int val) {
e[idx] = val; // 赋值
ne[idx] = head; //头插法, 让新插入节点的指针指向原来头结点指向的位置
head = idx++; // 更新头结点信息,同时idx自加一次
}
删除第k个插入的数据后面的那个数据:
// 将下标是 k的点后面的点删掉
private static void remove(int k) {
ne[k] = ne[ne[k]]; // 让下标为 k的结点指向 下个结点的下个结点
}
插入在下标为k的点后面:
public static void Insert(int k, int x) {
e[idx] = x;
ne[idx] = ne[k];
ne[k] = idx++;
}
个人思考(此处k等价于从外界输入的数字,从1开始,第一个位置.....):
- 关于idx的值与k的值
- idx初始为0,即插入的第一个数据下标为ne[0],同时如果ne[0]后面还有元素则ne[0] = 1,指向下一个元素,否则ne[0] = head即-1。同理可得链表中最后一个元素的指向为-1。
- k,第k个插入的数据为e[k-1],同理第k个插入的数据下标指向为ne[k-1],这样删除第k个插入的数据的后方的一个数据的方法就是 ne[k-1] = ne[ne[k-1]]。若k=0,即删除头节点head = ne[head];
- 在第k个数字后再插入一个数,就是e[idx] = var,ne[idx] = ne[k-1],ne[k-1] = idx