LinkedList源码阅读笔记(1),2024年最新java毕业设计参考题目及答案

}

属性


看一下LinkedList的主要属性。first和last对应了双链表的头结点和尾结点。

在这里插入图片描述

//元素个数

transient int size = 0;

//头结点

transient Node first;

//尾结点

transient Node last;

构造函数


//无参

public LinkedList() {

}

//从其它集合中构造

public LinkedList(Collection<? extends E> c) {

this();

addAll©;

}

获取元素


双向链表的灵活处就是链表中的一个元素结构就可以向左或者向右开始遍历查找需要的元素结构。因此对于一个有序链表,查询的效率比单链表高一些。因为,我们可以记录上次查找的位置 p,每次查询时,根据要查找的值与 p 的大小关系,决定是往前还是往后查找,所以平均只需要查找一半的数据。

链表查询示意图如下:

在这里插入图片描述

//根据索引获取数据

public E get(int index) {

//越界判断

checkElementIndex(index);

//根据index获取节点

return node(index).item;

}

//根据索引获取节点

Node node(int index) {

// 因为是双链表

// 所以根据index是在前半段还是后半段决定从前遍历还是从后遍历

// 这样index在后半段的时候可以少遍历一半的元素

if (index < (size >> 1)) {

// 如果是在前半段

// 就从后往前遍历

Node x = first;

for (int i = 0; i < index; i++)

x = x.next;

return x;

} else {

//如果是在前半段

//就从前往后遍历

Node x = last;

for (int i = size - 1; i > index; i–)

x = x.prev;

return x;

}

}

添加元素


  • 头插法

private void linkFirst(E e) {

// 首节点

final Node f = first;

// 创建新节点,新节点的next是首节点

final Node newNode = new Node<>(null, e, f);

first = newNode;

// 判断链表是不是为空

// 如果是就把last也置为新节点

// 否则把原首节点的prev指针置为新节点

if (f == null)

last = newNode;

else

f.prev = newNode;

//元素个数加1

size++;

// 修改次数 +1,用于 fail-fast 处理

modCount++;

}

public void addFirst(E e) {

linkFirst(e);

}

  • 尾插法

void linkLast(E e) {

//尾结点

final Node l = last;

//新节点

final Node newNode = new Node<>(l, e, null);

//尾结点置为新节点

last = newNode;

//如果链表为空,头结点指向尾结点

if (l == null)

first = newNode;

else

l.next = newNode;

//元素个数加1

size++;

// 修改次数 +1,用于 fail-fast 处理

modCount++;

}

public void addLast(E e) {

linkLast(e);

}

public boolean add(E e) {

linkLast(e);

return true;

}

在链表头部和尾部插入时间复杂度都是O(1),头插法和尾插法的示意图如下:

在这里插入图片描述

  • 中间插入法:中间插入需要找到插入位置节点,改变该节点的前趋和该节点前趋节点的后继

在这里插入图片描述

//根据索引插入节点

public void add(int index, E element) {

//判断是否越界

checkPositionIndex(index);

//未插入

if (index == size)

linkLast(element);

else

//找到索引位置节点,在该节点前插入新节点

linkBefore(element, node(index));

}

// 在节点succ之前添加元素

void linkBefore(E e, Node succ) {

//节点succ的前趋节点

final Node pred = succ.prev;

//新节点

final Node newNode = new Node<>(pred, e, succ);

//改变节点succ的前趋指向

succ.prev = newNode;

// 判断前置节点是否为空

// 如果为空,说明是第一个添加的元素,头结点重新赋值

// 否则修改前置节点的next为新节点

if (pred == null)

first = newNode;

else

pred.next = newNode;

//元素个数加1

size++;

// 修改次数 +1,用于 fail-fast 处理

modCount++;

}

在中间添加元素效率低一些,首先要先找到插入位置的节点,再修改前后节点的指针,时间复杂度为O(n)。

删除元素


双链表中删除元素只需要改变前趋和后继的指向。

  • 删除头节点

//删除头节点

public E removeFirst() {

final Node f = first;

//如果链表为空,抛出异常

if (f == null)

throw new NoSuchElementException();

// 删除首节点

return unlinkFirst(f);

}

// 删除头节点

private E unlinkFirst(Node f) {

// 头结点

final E element = f.item;

//头结点后继节点

final Node next = f.next;

//头结点数据域后继置空,帮助GC

f.item = null;

f.next = null;

//头结点置为后继节点

first = next;

// 如果只有一个元素,删除了,把last也置为空

// 否则把next的前趋置为空

if (next == null)

last = null;

else

next.prev = null;

size–;

modCount++;

//返回删除的节点

return element;

}

  • 删除尾结点

//删除尾结点

public E removeLast() {

//尾结点

final Node l = last;

//链表为空,抛出异常

if (l == null)

throw new NoSuchElementException();

return unlinkLast(l);

}

//删除尾结点

private E unlinkLast(Node l) {

// 尾结点元素

final E element = l.item;

//尾结点前趋节点

final Node prev = l.prev;

//尾结点数据、前趋置为null,帮助GC

l.item = null;

l.prev = null;

//尾结点置为前趋节点

last = prev;

// 如果只有一个元素,删除了把first置为空

// 否则把前置节点的next置为空

if (prev == null)

first = null;

else

prev.next = null;

size–;

modCount++;

//返回删除的节点

return element;

}

注意:

不管是上一节的头插入和未插入,还是这一节的删除头节点和删除尾结点,都没有在List中定义。前面提到,LinkedList实现了Deque接口,所以这是作为双向队列的LinkedList插入和删除元素的方式。还有获取头结点和尾结点的方法getFirst()和getLast(),同样都是双向队列的实现。

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数同学面临毕业设计项目选题时,很多人都会感到无从下手,尤其是对于计算机专业的学生来说,选择一个合适的题目尤为重要。因为毕业设计不仅是我们在大学四年学习的一个总结,更是展示自己能力的重要机会。

因此收集整理了一份《2024年计算机毕业设计项目大全》,初衷也很简单,就是希望能够帮助提高效率,同时减轻大家的负担。
img
img
img

既有Java、Web、PHP、也有C、小程序、Python等项目供你选择,真正体系化!

由于项目比较多,这里只是将部分目录截图出来,每个节点里面都包含素材文档、项目源码、讲解视频

如果你觉得这些内容对你有帮助,可以添加VX:vip1024c (备注项目大全获取)
img

tLast(),同样都是双向队列的实现。**

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数同学面临毕业设计项目选题时,很多人都会感到无从下手,尤其是对于计算机专业的学生来说,选择一个合适的题目尤为重要。因为毕业设计不仅是我们在大学四年学习的一个总结,更是展示自己能力的重要机会。

因此收集整理了一份《2024年计算机毕业设计项目大全》,初衷也很简单,就是希望能够帮助提高效率,同时减轻大家的负担。
[外链图片转存中…(img-wHUCmN4e-1712527712544)]
[外链图片转存中…(img-zJP0QLTY-1712527712545)]
[外链图片转存中…(img-CWSc3BlN-1712527712545)]

既有Java、Web、PHP、也有C、小程序、Python等项目供你选择,真正体系化!

由于项目比较多,这里只是将部分目录截图出来,每个节点里面都包含素材文档、项目源码、讲解视频

如果你觉得这些内容对你有帮助,可以添加VX:vip1024c (备注项目大全获取)
[外链图片转存中…(img-GhqJT7cj-1712527712545)]

  • 11
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值