【数据结构】链表与实现分析

概念

 

(百度百科)链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。我相信,链表结构也是从我们显示生活中演绎出来的,例如我们的项链、铁链等都是一种链表结构的生活写照。链表和数组一样,都是数据结构中最为基础的线性结构,许多的其它数据结构,都是站在这两位“巨人”的肩膀上。下面来看看链表具有什么样的特性:

链表是由各结点组成的,每个结点相当于数据结构中的数据单元,这些数据单元以一种“链”的形式组成的方式,就称为链表结构。好比如一条铁链,每个“铁环”就相当于链接中的结点,每个结点与结点相扣就组成了一条链。抽象出来,就像上图描述的那样。从图中可以看出,链表有两个主要部分。一个是结点本身,从计算机角度解释就是数据本身;还有一部分就是数据与数据关联的“指针”,而这个指针在现实生活的链表结构事物中是不存在的,只是为了能在虚拟环境中模拟真实环境的一种手段。这个指针就是整条链表的粘合剂,是用来描述现实中一条铁链的各个链环扣在一起的“扣”这个动作。我们都知道,铁链的各个铁环(结点)是可以随意在某个位置解开某个铁环和增加铁环,且每个铁环是没有顺序可言的,说白了,链表这是纯粹的把各个部分串连起来。

在数据结构中对链接又有分单向链表、双向链表和循环链表三类。在这里还是以铁链为例,我现在需要加长铁链的长度,而只允许在铁链的一端追加铁环,这就叫单向链表;如果在链的两端都能增加,那就叫双向链表;如果我把铁链两端也就是铁链的首和尾扣在一起就形成了一条闭环的项链,那就叫循环链表。无论单向还是双向,所有“扣”的这个动作都是依赖“指针”来实现。单向链表只有一个指向下一个铁环的指针;而双向链表的铁环分别有指向前后铁环的指针;循环链表则是链尾指向链头从而形成循环状的结构。

 

实现分析

 

链表作为数据结构中最基础的结构之一,使用范围之广不用多说,例如下一篇“栈”的学习同样会用到链表作为底层的实现支撑。为了能看清楚链接在计算机领域的实现,接下来看看Java语言的LinkedList实例源码作为分析对象:

/*LinkedList实例参数*/
private transient Entry<E> header = new Entry<E>(null, null, null); //链表实体,比如铁链中的铁环
private transient int size = 0; //链表长度

继续深入观察到底“铁环”是怎样构成的:

private static class Entry<E> {
    E element;
    Entry<E> next;
    Entry<E> previous;

    Entry(E element, Entry<E> next, Entry<E> previous) {
        this.element = element;  //数据内容,就是“铁环”本身
        this.next = next;  //指向下一个铁环的指针,就是向后“扣”的动作
        this.previous = previous;  //指向上一个铁环的指针,就是向前“扣”的动作
    }
}

这个Entry实体类是LinkedList的内部类,从Entry的属性可以看出,这个LinkedList是一个双向链表。再来看看LinkedList的增加操作:

public boolean add(E e) {
    addBefore(e, header);
    return true;
}

其中addBefore是Entry内部类的方法:

private Entry<E> addBefore(E e, Entry<E> entry) {
    Entry<E> newEntry = new Entry<E>(e, entry, entry.previous);
    newEntry.previous.next = newEntry;
    newEntry.next.previous = newEntry;
    size++;
    modCount++;
    return newEntry;
}

说白了,这些操作方法都是现实的写照,不需要被这些方法所迷惑。想要弄懂链表结构的特性,自己找条铁链折腾两下就懂了。你能做的,代码都能实现。当然,前提是符合逻辑。

原文地址:https://www.cnblogs.com/wcd144140/p/5337514.html