首页 > 编程语言 >4-LinkedList底层结构和源码分析

4-LinkedList底层结构和源码分析

时间:2024-07-12 11:58:22浏览次数:13  
标签:Node 结点 last LinkedList 链表 源码 first 底层

4-LinkedList底层结构和源码分析

介绍汇总:

  1. LinkedList的全面说明
  2. LinkedList的底层操作机制
  3. LinkedList的运行重要步骤
  4. ArrayList 和 LinkedList 比较

1-LinkedList的全面说明

  1. LinkedList 底层实现了双向链表和双端队列特点
  2. 可以添加任意元素(元素可以重复),包括 null
  3. 线程不安全,没有实现同步

2-LinkedList的底层操作机制

  1. LinkedList 底层维护了一个双向链表。
  2. LinkedList 中维护了两个属性 first 和 last 分别指向 首节点和尾节点。
  3. 每个节点(Node 对象),里面又维护了 prev、next、item 三个属性,其中通过 prev 指向前一个,通过 next 指向后一个节点,最终实现双向链表。
  4. 所以 linkedList 的元素的添加和删除,不是通过数组完成,相对来说效率较高(仅需改变几个指针,无需移动数据)。
  5. 模拟一个简单的双向链表
// 节点代码
class Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;

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

// 简单双向列表
class LinkedList {
    int size = 0;

    Node<E> first;

    Node<E> last;
}

3-LinkedList的运行重要步骤

  1. 构造器

​ 因为双向链表是通过指针指向内存中的数据节点,形成一个链的集合,所以为啥叫双向链表。所以存储的东西只有指针、大小,也并没有扩容机制,只要不超出规定的内存,理论上可以无限添加数据。

  1. 这里主要 debug 看源码就可以搞清楚了,关键是每个方法的具体使用的算法,比较有意思。
  2. 具体算法介绍
// 添加数据为链表第一个,也就是 first 指向的
// 具体流程:
// 1. 根据 first 指针获取当前第一个数据结点
// 2. 创建一个参数为 first 指向为空(第一个结点),数据值,
// 		last 指向当前链表中第一个数据结点的新结点
// 3. 将 first 指向新结点
// 4. 判断加入之前 first 指向是否为空,若为空说明链表为空,则把 last 也指向新结点
// 		反之,说明链表中有数据,而之前 first 指向的数据节点 prev 为 null 所以把之前的
// 		第一个结点的 prev 指向当前的新结点
// 5. 记得一定要将数据个数或长度 + 1 以及链表修改记录
private void linkFirst(E e) {
        final Node<E> f = first;
        final Node<E> newNode = new Node<>(null, e, f);
        first = newNode;
        if (f == null)
            last = newNode;
        else
            f.prev = newNode;
        size++;
        modCount++;
}

// 添加数据为链表最后一个,也就是 last 指向的
// 具体流程:
// 1. 根据 last 指针获取当前最后一个数据结点
// 2. 创建一个参数为 first 指向为当前链表中最后一个数据节点,数据值,
// 		last 指向为空(最后一个结点)的新结点
// 3. 将 last 指向新结点
// 4. 判断加入之前 last 指向是否为空,若为空说明链表为空,则把 first 也指向新结点
// 		反之,说明链表中有数据,而之前 last 指向的数据节点 next 为 null 所以把之前的
// 		最后一个结点的 next 指向当前的新结点
// 5. 记得一定要将数据个数或长度 + 1 以及链表修改记录
void linkLast(E e) {
        final Node<E> l = last;
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
}

// 根据索引寻找数据值
// 将链表长度除以 2 ,然后根据该结果与索引的大小比较
// 大的话,说明数据节点离最后一个节点近
// 小的话,说明数据节点离第一个节点近
// 然后开始进行遍历循环匹配索引值的数据节点
Node<E> node(int index) {
        // assert isElementIndex(index);

        if (index < (size >> 1)) {
            Node<E> x = first;
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        } else {
            Node<E> x = last;
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;
        }
}

4-ArrayList 和 LinkedList 比较

  1. ArrayList 和 LinkedList 区别
集合 底层结构 增删的效率 改查的效率
ArrayList 可变数组 较低数组扩容 较高
LinkedList 双向链表 较高,通过链表追加 较低
  1. 如何选择 ArrayList 和 LinkedList
    1. 若改查的操作多,选择 ArrayList
    2. 若增删的操作多,选择 LinkedList
    3. 常规来说,程序中,80% - 90% 都是查询,因此大部分情况下选择 ArrayList
    4. 在一个项目中,根据业务灵活选择,也可能这样,一个模块使用的是 ArrayList ,另外一个模块是 LinkedList 。也就是说,要根据业务进行选择

标签:Node,结点,last,LinkedList,链表,源码,first,底层
From: https://www.cnblogs.com/Yao-happy/p/18298043

相关文章

  • 毕业设计-基于Springboot+Vue的招生管理系统的设计与实现(源码+LW+包运行)
    源码获取:https://download.csdn.net/download/u011832806/89456200基于SpringBoot+Vue的招生管理系统开发语言:Java数据库:MySQL技术:SpringBoot+MyBatis+Vue.js工具:IDEA/Ecilpse、Navicat、Maven系统演示视频:链接:https://pan.baidu.com/s/1GwKRBbuwMiZmnxkvRN9VJg?pwd=sb......
  • 毕业设计-基于Springboot+Vue的致远汽车租赁系统的设计与实现(源码+LW+包运行)
    源码获取:https://download.csdn.net/download/u011832806/89456206基于SpringBoot+Vue的致远汽车租赁系统开发语言:Java数据库:MySQL技术:SpringBoot+MyBatis+Vue.js工具:IDEA/Ecilpse、Navicat、Maven系统演示视频:链接:https://pan.baidu.com/s/1IHfaizhpMI1q750DBZ1enA?pw......
  • 毕业设计-基于Springboot+Vue的智慧外贸平台的设计与实现(源码+LW+包运行)
    源码获取:https://download.csdn.net/download/u011832806/89456212基于SpringBoot+Vue的智慧外贸平台开发语言:Java数据库:MySQL技术:SpringBoot+MyBatis+Vue.js工具:IDEA/Ecilpse、Navicat、Maven系统演示视频:链接:https://pan.baidu.com/s/1PnEjpc6IXOgPmYxluTOr2g?pwd=kv......
  • 经典再现,回顾常见排序算法之冒泡排序,附Java源码及优化改进实现
    回顾一下排序算法,老酒装新瓶,给自己的技能点做个回放。排序(Sorting)是计算机程序设计中的一种重要操作,它的功能是将一个数据元素(或记录)的任意序列,重新排列成一个有序的序列,也可以理解为高矮个站队。衡量排序算法的两个指标,时间复杂度和稳定性。举个例子,如果我们的数据......
  • Java计算机毕业设计的网上电影售票系统(开题报告+源码+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着互联网技术的飞速发展和人们生活节奏的加快,网络购物、在线娱乐等数字化生活方式已成为主流。电影作为大众喜爱的文化娱乐形式之一,其售票方式也经......
  • Java计算机毕业设计信息工程学院实验室管理系统(开题+源码+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着信息技术的飞速发展,信息工程学院作为培养未来科技人才的重要基地,其实验室管理日益复杂化与多样化。传统的手工管理方式已难以满足高效、精准、安......
  • 基于java+springboot+vue实现的在线教育系统(文末源码+Lw)111
    基于SpringBoot+Vue的实现的在线教育系统(源码+数据库+万字Lun文+流程图+ER图+结构图+演示视频+软件包)系统功能:本在线教育系统管理员功能有个人中心,用户管理,讲师管理,普通管理员管理,课程管理员管理,课程管理,课程分类管理,教师管理,名师管理,系统管理,订单管理。普通管理员和课程......
  • 基于java+springboot+vue实现的作业管理系统(文末源码+Lw)110
    基于SpringBoot+Vue的实现的作业管理系统(源码+数据库+万字Lun文+流程图+ER图+结构图+演示视频+软件包)功能描述:作业管理系统有管理员,教师,学生三个角色。教师和学生都可以进行注册然后再登录。学生可以修改自己的密码,查看和下载作业信息,并且可以提交自己写好的作业,并且可以......
  • 2-ArrayList底层结构和源码分析
    2-ArrayList底层结构和源码分析介绍汇总:ArrayList的注意事项ArrayList的运行重要步骤补充1-ArrayList的注意事项ArrayList允许添加所有的元素,包括null,而且还可以多个null。ArrayList是由数组来实现数据存储的。ArrayList基本等同于Vector,除了ArrayList是线......
  • Go 语言 UUID 库 google/uuid 源码解析:UUID version4 的实现
    google/uuid库地址本文将解析googl/uuid库中UUID变体10版本4的实现。版本4的UUID采取完全随机的方式实现,简单来说就是将UUID中的122位全部随机填充(剩余的6位作标记位)。版本4的UUID存在一定的重复风险,但就如源码注释中所说:“一年内创建几十万亿个UUI......