1、数组模拟单链表
1.1图示
- 原先的单链表都是一个个的Node节点,Node有data域和next域,每一个Node都是一个单独的对象,每一个Node使用next关联起来形成一个链表。
- 现在使用数组模拟链表,我们使用两个数组,一个
E[]数组,存储的是data,一个Ne[]数组,存储当前节点的下一个节点的索引值
。如下图所示。并且使用两个指针,一个是head指针,指向头结点(非虚拟头结点,这里是第一个节点),一个是idx指针,指向待插入节点的位置, 注意:最后一个节点的next为-1
1.2代码实现
1.2.1初始化
初始化时我们需要先创建两个数组,和两个指针(索引),head置为-1,idx置为0
此时链表中还没有节点,所以head指向-1。
因为idx指向的是待插入节点的位置,当链表为空时,待插入的节点就是第一个位置,即索引为0
public class ArrayLinkedList{
static int[] e;
static int[] next;
//头结点的索引
static int head;
//待插入节点的索引
static int idx;
static void init() {
e = new int[10010];
next = new int[10010];
head = -1;
idx = 0;
}
}
1.2.3头插法
在链表的头部添加一个节点
static void addHead(int data) {
e[idx] = data; //为新节点的data域赋值
next[idx] = head; //将新节点的next指向原来的头结点 刚开始时head是-1,
//所以第一个节点的next就是-1 最后一个节点的next总是-1
//遍历时可以作为终止条件
head = idx; //将head指向新的头结点head
idx++; //idx++ 继续指向待插入节点的位置
}
1.2.3在索引为k的节点后插入一个节点
跟普通的链表的插入都是类似的,先将待插入节点指向原节点的next,然后将原节点指向待插入节点
static void insertAfter(int k ,int data){
e[idx] = data; //为新节点的data域赋值
ne[idx] = ne[k]; //新节点的next指向原第k个节点的next
ne[k] = idx; //第k个节点的next指向新节点
idx++; //idx++ 继续指向待插入节点的位置
}
1.2.4删除索引为k的节点的后面的一个节点
static void delAfter(int k){
//删除的是头结点 就将头节点指向下一个节点
if(k==0)head = ne[head];
//不是头结点 就将k索引的直接指向k后面的第二个节点
else ne[k] = ne[ne[k]];
}
1.2.5遍历
这里的终止条件就是某一个节点的next为-1
for (int i = head; i != -1; i = ne[i]){
System.out.println(e[i]);
}
1.3练习
2、数组模拟双向链表
2.1图示
数组模拟双向链表和模拟单链表类似,只是多了一个数组,存储的是上一个节点的索引,而且我们为了不考虑边界问题,将索引为0的节点作为整个链表的左边界,将索引为1的节点作为整个链表的右边界
,只考虑删除和插入即可,idx指针
还是指向待插入位置的索引
2.2代码示例
2.2.1初始化
根据上面的分析,这里要使用三个数组
public class DoubleArrayLinkedList {
static int[] e;
static int[] l;
static int[] r;
//待插入节点的索引
static int idx;
static void init() {
e = new int[10010];
l = new int[10010];
r = new int[10010];
l[1] = r[0];
r[0] = l[1];
//因为0和1代表左右边界,所以idx第一次指向2的位置
idx = 2;
}
}
2.2.2在第k个插入的节点后插入一个节点
static void insertAfter(int k, int data) {
e[idx] = data;
//先将第k个插入的节点的右边的节点整好双向连上新节点
r[idx] = r[k];
l[r[k]] = idx;
//将第k个插入的节点双向连上新节点
r[k] = idx;
l[idx] = k;
idx++;
}
2.2.3删除插入的第k个节点
static void remove(int k) {
//k的右边的左边等于k的左边
l[r[k]] = l[k];
//k的左边的右边等于k的右边
r[l[k]] = r[k];
}
2.2.4遍历
从索引为0的位置开始遍历,当遍历到索引为1时终止
扫描二维码关注公众号,回复:
13358457 查看本文章
for(int i = r[0];i!=1;i=r[i]){
System.out.println(e[i]);
}