你们经过前几章的学习,明白了什么是单链表,相比于顺序存储,在插入和删除方面,它的性能更加优越,可是小伙子们,有没有想过在C语言和Java出现以前,只有Basic等早期语言,而这些语言没有相似指针和地址的概念,那我们编程界的六道仙人是如何来描述链表的尼?java
对于没有指针的编程语言,能够用数组替代指针,来描述链表。让数组的每一个元素由data和cur两部分组成,其中cur至关于链表的next指针,这种用数组描述的链表叫作静态链表。这种描述方法叫作游标实现法 ,存储方式以下图所示git
固然,还有几点规则github
(注:如上图下标0或者下标999,这两个位置数据为空)编程
(注:如该数组第一个没有存放数据的元素的下标是5,因此第一个元素的游标是第一个没有存放数据元素的下标,也就是说,下标0元素的游标也是5)数组
(注:第一个存储元素的下标为1,那么最后一个元素的游标就是1)编程语言
也就是这样性能
/** * 静态链表中的对象 * */
public class Node<T> {
// 数据
T data;
// 游标
int cur;
}
/** * 静态链表 * */
public class StaticLinkedList<T> {
// 封装的数组
private Node<T>[] arr;
/** * 初始化 * */
public StaticLinkedList(int length){
arr = new Node[length];
for(int i = 0; i < arr.length ;i++){
arr[i] = new Node<>();
// 非特殊点的元素游标为下一个元素的下标,
// 第一个元素游标为除特殊点外,第一个没有数据的元素下标,如今链表为空,因此第一个元素的游标为1
arr[i].cur = i + 1;
}
// 最后一个元素的游标为第一个存储数据元素的下标,可是如今链表为空,因此它的游标为0
arr[arr.length - 1].cur = 0;
}
}
复制代码
完事以后就是这个熊样学习
插入以前,先获取空位下标,也就是说,要将数据插到哪spa
/** * 获取空闲结点的下标 * */
public int getEmptyNodeIndex(){
// 获取第一个元素的游标,也就是一个数组中,第一个空闲元素的下标。默认为0
int i = arr[0].cur;
if(i != 0){
// 第一个元素的游标指向的是数组中第一个数据无值的元素下标,由于要将空闲位置插入元素,
// 因此将第一个元素(下标为0)的游标指向要插入值的元素以后的空闲元素下标
arr[0].cur = arr[i].cur;
}
return i;
}
复制代码
注:如上图所示,0号位置指向的是第一个空值的下标,也就是1号元素,因此先把1号元素取出,看看是否是最后一个元素,最后一个元素的游标为0,不是最后一个元素,就将它取出返回,由于要将数据插到这,因此0号元素的游标指向了2号元素,由于如今2号元素的是空值。.net
好,获取完空位坐标以后,就开始插入元素了
(代码)
/** * 插入数据 * */
public void addDataByIndex(int index, T value){
// 判断插入的位置是否有效
if(index < 0 || index > arr.length){
throw new IllegalArgumentException("位置无效");
}
// 第一步:获取可插入的位置下标
int emptyNodeIndex = getEmptyNodeIndex();
// 将数据插入
arr[emptyNodeIndex].data = value;
// 更新最后一个元素的游标,它指向的是第一个有数据元素的下标
int k = arr.length - 1;
// 第二步:根据要插入的是第几个位置,安装个数,从最后一个元素的游标开始往前推导,找出该元素所在游标
for(int i = 1; i <= index - 1; i++){
k = arr[k].cur;
}
// 更新刚插入数据的元素的游标为,他上一个元素的游标,也就是0,由于是从最后一个元素开始推的
arr[emptyNodeIndex].cur = arr[k].cur;
// 更新它上一个元素的游标为当前元素下标
arr[k].cur = emptyNodeIndex;
}
复制代码
也就是这样
同窗们,学会了吗