《数据结构系列_线性表_链式存储之静态链表》

1.简介

大家通过前几章的学习,明白了什么是单链表,相比于顺序存储,在插入和删除方面,它的性能更加优越,但是小伙子们,有没有想过在C语言和Java出现之前,只有Basic等早期语言,而这些语言没有类似指针和地址的概念,那咱们编程界的六道仙人是如何来描述链表的尼?

对于没有指针的编程语言,可以用数组替代指针,来描述链表。让数组的每个元素由data和cur两部分组成,其中cur相当于链表的next指针,这种用数组描述的链表叫做静态链表。这种描述方法叫做游标实现法 ,存储方式如下图所示

当然,还有几点规则

  1. 我们对数组的第一个和最后一个元素做特殊处理,从数据来说:这两个位置不存放数据
    (注:如上图下标0或者下标999,这两个位置数据为空)

  2. 这两个位置,从游标来说,第一个(下标0)元素的游标为该数组第一个没有存放数据元素的下标。并通常将未使用的数组元素称为备用链表。也就是说,存放的是备用链表中的第一个元素下标
    (注:如该数组第一个没有存放数据的元素的下标是5,所以第一个元素的游标是第一个没有存放数据元素的下标,也就是说,下标0元素的游标也是5)

  3. 最后一个元素的游标为该数组第一个有数值的元素的下标,相当于头结点
    (注:第一个存储元素的下标为1,那么最后一个元素的游标就是1)

  4. 其余元素的游标均为他下一个元素的下标

也就是这样

2.对应操作

2.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;
    }
}

完事之后就是这个熊样

2.1 插入元素

插入之前,先获取空位下标,也就是说,要将数据插到哪

 /**
     * 获取空闲结点的下标
     * */
    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号元素的是空值。

好,获取完空位坐标之后,就开始插入元素

(代码)

    /**
     * 插入数据
     * */
    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;
    }

也就是这样

3.最后

同学们,学会了吗
代码在这里

发布了30 篇原创文章 · 获赞 78 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/u010302765/article/details/100669761