一篇文章带你彻底理解Java LinkedList数据结构详解
基本概念:
链表(Linked list)是一种常见的基础数据结构,它由一系列的节点(Node)组成,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的地址。每个节点包含两部分:数据元素和指向下一个节点的引用。
链表可分为单向链表和双向链表。
- **节点(Node):**链表中的每个元素称为节点,每个节点包含一个数据元素和一个指向下一个节点的引用。
- **头节点(Head):**链表中的第一个节点称为头节点,它是链表的入口。
- **尾节点(Tail):**链表中的最后一个节点称为尾节点,它的下一个节点引用为空(null)。
- 单向链表(Singly Linked List):每个节点只包含一个指向下一个节点的引用。
- **双向链表(Doubly Linked List):**每个节点包含一个指向下一个节点和一个指向前一个节点的引用,从而可以双向遍历链表。
一个单向链表包含两个值: 当前节点的值和一个指向下一个节点的链接。
一个双向链表有三个整数值: 数值、向后的节点链接、向前的节点链接。
链表的优点:
- **动态性:**链表的大小可以根据需要动态调整,可以灵活地插入和删除节点。
- **内存利用率高:**链表使用灵活的内存分配方式,不像数组需要一块连续的内存空间。
- **插入和删除操作效率高:**在链表中插入和删除节点的时间复杂度为O(1)(在已知节点位置的情况下)。
链表的缺点:
- **随机访问效率低:**链表中查找特定元素的效率较低,需要从头节点开始遍历链表。
- **内存消耗较大:**与数组相比,链表需要额外的存储空间来存储节点之间的引用。
总结: **链表是一种常用的数据结构,适合在动态插入和删除元素的场景中使用。**它的主要特点是节点之间通过引用连接起来,每个节点包含数据和指向下一个节点的引用。根据具体的需求,可以选择单向链表、双向链表来实现不同的功能。
那么如何区分使用ArrayList和LinkedList俩种数据结构呢?
Java LinkedList(链表) 类似于 ArrayList,是一种常用的数据容器。
与 ArrayList 相比,LinkedList 的增加和删除的操作效率更高,而查找和修改的操作效率较低。
以下情况使用 ArrayList :
- 频繁访问列表中的某一个元素。
- 只需要在列表末尾进行添加和删除元素操作。
以下情况使用 LinkedList :
- 需要通过循环迭代来访问列表中的某些元素。
- 需要频繁的在列表开头、中间、末尾等位置进行添加和删除元素操作。
LinkedList 继承了 AbstractSequentialList 类。
LinkedList 实现了 Queue 接口,可作为队列使用。
LinkedList 实现了 List 接口,可进行列表的相关操作。
LinkedList 实现了 Deque 接口,可作为队列使用。
LinkedList 实现了 Cloneable 接口,可实现克隆。
LinkedList 实现了 java.io.Serializable 接口,即可支持序列化,能通过序列化去传输。
LinkedList 类位于 java.util 包中,使用前需要引入它,语法格式如下:
// 引入 LinkedList 类
import java.util.LinkedList;
LinkedList<E> list = new LinkedList<E>(); // 普通创建方法
或者
LinkedList<E> list = new LinkedList(Collection<? extends E> c); // 使用集合创建链表
下面是链表LinkedList的增删改查和遍历操作的完整示例实例:
import java.util.LinkedList;
import java.util.Iterator;
public class LinkedListExample {
public static void main(String[] args) {
LinkedList<String> linkedList = new LinkedList<>();
// 在表头添加元素
linkedList.addFirst("A");
// 在表尾添加元素
linkedList.addLast("B");
// 在指定位置添加元素
linkedList.add(1, "C");
// 遍历链表
System.out.println("链表内容:");
for (String element : linkedList) {
System.out.println(element);
} //首先,通过 addFirst 方法将元素 "A" 添加到链表的表头,此时链表中的元素为 "A"。接着,使用 addLast 方法将元素 "B" 添加到链表的表尾,此时链表中的元素变为 "A"、"B"。最后,通过 add 方法在索引 1 的位置插入元素 "C",此时链表中的元素变为 "A"、"C"、"B"。
// 修改指定位置的元素
linkedList.set(1, "D");
System.out.println("------------------------");
System.out.println("修改指定位置的元素后的链表内容:");
for (String element : linkedList) {
System.out.println(element);
}
// 删除表头元素
linkedList.removeFirst();
// 删除表尾元素
linkedList.removeLast();
// 删除指定位置的元素
linkedList.remove(0);
System.out.println("-----------------------");
System.out.println("删除指定位置的元素后链表内容:");
for (String element : linkedList) {
System.out.println(element);
}
// 查询元素
System.out.println("链表是否包含元素 C: " + linkedList.contains("C"));//false
// 使用 for 循环遍历
for (int i = 0; i < linkedList.size(); i++) {
System.out.println(linkedList.get(i));
}
// 使用迭代器遍历
Iterator<String> iterator = linkedList.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
// 使用 for-each 循环遍历
for (String item : linkedList) {
System.out.println(item);
}
}
}
对于上面的代码示例,输出结果如下:
链表内容:
A
C
B
------------------------
修改指定位置的元素后的链表内容:
A
D
B
-----------------------
删除指定位置的元素后链表内容:
链表是否包含元素 C: false
Java LinkedList 方法
Java LinkedList 常用方法列表如下:
方法 | 描述 |
---|---|
public boolean add(E e) | 链表末尾添加元素,返回是否成功,成功为 true,失败为 false。 |
public void add(int index, E element) | 向指定位置插入元素。 |
public boolean addAll(Collection c) | 将一个集合的所有元素添加到链表后面,返回是否成功,成功为 true,失败为 false。 |
public boolean addAll(int index, Collection c) | 将一个集合的所有元素添加到链表的指定位置后面,返回是否成功,成功为 true,失败为 false。 |
public void addFirst(E e) | 元素添加到头部。 |
public void addLast(E e) | 元素添加到尾部。 |
public boolean offer(E e) | 向链表末尾添加元素,返回是否成功,成功为 true,失败为 false。 |
public boolean offerFirst(E e) | 头部插入元素,返回是否成功,成功为 true,失败为 false。 |
public boolean offerLast(E e) | 尾部插入元素,返回是否成功,成功为 true,失败为 false。 |
public void clear() | 清空链表。 |
public E removeFirst() | 删除并返回第一个元素。 |
public E removeLast() | 删除并返回最后一个元素。 |
public boolean remove(Object o) | 删除某一元素,返回是否成功,成功为 true,失败为 false。 |
public E remove(int index) | 删除指定位置的元素。 |
public E poll() | 删除并返回第一个元素。 |
public E remove() | 删除并返回第一个元素。 |
public boolean contains(Object o) | 判断是否含有某一元素。 |
public E get(int index) | 返回指定位置的元素。 |
public E getFirst() | 返回第一个元素。 |
public E getLast() | 返回最后一个元素。 |
public int indexOf(Object o) | 查找指定元素从前往后第一次出现的索引。 |
public int lastIndexOf(Object o) | 查找指定元素最后一次出现的索引。 |
public E peek() | 返回第一个元素。 |
public E element() | 返回第一个元素。 |
public E peekFirst() | 返回头部元素。 |
public E peekLast() | 返回尾部元素。 |
public E set(int index, E element) | 设置指定位置的元素。 |
public Object clone() | 克隆该列表。 |
public Iterator descendingIterator() | 返回倒序迭代器。 |
public int size() | 返回链表元素个数。 |
public ListIterator listIterator(int index) | 返回从指定位置开始到末尾的迭代器。 |
public Object[] toArray() | 返回一个由链表元素组成的数组。 |
public T[] toArray(T[] a) | 返回一个由链表元素转换类型而成的数组。 |
更多 API 方法可以查看:https://www.runoob.com/manual/jdk11api/java.base/java/util/LinkedList.html
结尾语:记录于2023年8月5号17时15分,以上仅为个人在[Java数据结构LinkedList—Java高级编程—菜鸟教程](Java LinkedList | 菜鸟教程 (runoob.com))的学习过程中遇到的问题,还有记录的个人想法,有错误欢迎指出,希望对您有帮助,感谢观看!如果可以的话,点点赞,点点关注