LinkedList学习总结

本文详细解析了LinkedList的数据结构原理,包括其内部实现机制、节点链接方式及关键操作如添加、查询等的实现过程。此外还介绍了LinkedList作为堆栈、队列或双端队列使用的特点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LinkedList集合,是一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作。LinkedList 是非同步的。

LinkedList是通过节点直接彼此连接来实现的。每一个节点都包含前一个节点的引用,后一个节点的引用和节点存储的值。当一个新节点插入时,只需要修改其中保持先后关系的节点的引用即可,当删除记录时也一样。这样就带来以下有缺点:
操作其中对象的速度快 只需要改变连接,新的节点可以在内存中的任何地方
不能随即访问 虽然存在get()方法,但是这个方法是通过遍历接点来定位的所以速度慢。

以下是初步学习LinkedList源码总结而成,仅供参考。

public class JLinkedList {

//定义链表头
Node<E> first;
//定义链表尾
Node<E> last;
//定义链表长度,即size
int size;
//定义默认的添加方法
public boolean add(E e) {
    linkLast(e);
    return true;
}
//定义链表插入方法,和JDK自带方法一致,为插入不是替换
public void add(int index, E e){
    checkIndexMul(index);
    if (index == size)      //长度为链表长度,即为在末尾追加,和add(E e)方法一致
        linkLast(e);
    else                    //在链表长度以内,则插入链表
        linkBefore(e,node(index));
}
//插入链表具体方法,node为当前节点原始的值
private void linkBefore(E e, Node<E> node) {
    Node<E> beforeNode = node.prev;                         //取出当前节点的前一节点
    Node<E> newNode = new Node<E>(beforeNode,e,node);       //用前一节点和当前原始节点构造出新的节点值
    node.prev = newNode;                                    //将节点前后链接起来,双向链表,顺向逆向都要串联起来
    if (beforeNode != null)
        beforeNode.next = newNode;
    else
        first = newNode;
    size++;
}

//检查节点,抛出异常
private void checkIndexMul(int index) {
    if (!checkIndexMulException(index)){
        throw new IndexOutOfBoundsException("size out of bounds exception. size="+size+",index="+index);
    }
}

private boolean checkIndexMulException(int index) {
    return index >= 0 && index <= size;
}

//在链表结尾进行插入
void linkLast(E e){
    Node<E> l = last;                                       //若链表为空,则last为空,否则则为链表尾节点
    Node<E> newNode = new Node<E>(l,e,null);           //构造出新添加节点
    last = newNode;                                         //重置链表尾节点
    if (size == 0)
        first = newNode;
    else
        l.next = newNode;
    size++;
}

public E get(int index){
    checkIndex(index);
    return node(index).element;
}

private Node<E> node(int index) {
    if (index < (size >> 1)){                               //size>>1, 即为获取当前链表一半的长度,进行二分法查询,增加效率
        Node<E> indexNode = first;
        for (int i=0; i<index; i++)
            indexNode = indexNode.next;                     //链表查询耗时之处,需要从链表头到尾依次查询
        return indexNode;
    }else {
        Node<E> indexNode = last;
        for (int i=size-1; i>index; i--)
            indexNode = indexNode.prev;
        return indexNode;
    }
}

private void checkIndex(int index) {
    if (!checkIndexException(index)){
        throw new IndexOutOfBoundsException("size out of bounds exception. size="+size+",index="+index);
    }
}

private boolean checkIndexException(int index) {
    return index >= 0 && index < size;
}

public int size() {
    return size;
}

private static class Node<E>{                                  //链表节点
    Node<E> prev;                                              //存放上一节点的内存地址
    Node<E> next;                                              //存放下一节点的内存地址
    E element;                                                 //存放元素内容

    public Node(Node<E> prev, E element, Node<E> next) {
        this.prev = prev;
        this.next = next;
        this.element = element;
    }
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值