分步解析
- 该类
Node
表示链表中的单个节点。它有两个字段:data
,它保存存储在节点中的数据,和next
,它是对列表中下一个节点的引用。
public class Node {
int data;
Node next;
}
- 该类
LinkedList
表示链表数据结构。它有一个字段 ,head
它是对列表中第一个节点的引用。该类LinkedList
还有几个用于插入、删除和显示列表元素的方法。
public class LinkedList {
Node head;
public void insertAtBeginning(int data) {
// ...
}
public void insertAtEnd(int data) {
// ...
}
public void insertAfter(Node prevNode, int data) {
// ...
}
public void deleteNode(int key) {
// ...
}
public void display() {
// ...
}
}
- 该
insertAtBeginning()
方法在列表的开头插入一个新节点。它创建一个新节点,将其data
字段设置为给定数据,并将其next
字段设置为列表的当前头部。最后,它更新指向新节点的head
字段。LinkedList
public void insertAtBeginning(int data) {
Node newNode = new Node();
newNode.data = data;
newNode.next = head;
head = newNode;
}
- 该
insertAtEnd()
方法在列表末尾插入一个新节点。它创建一个新节点并将其data
字段设置为给定数据。如果列表为空,它会将 的head
字段设置LinkedList
为新节点。否则,它遍历列表找到最后一个节点并将其next
字段设置为新节点。
public void insertAtEnd(int data) {
Node newNode = new Node();
newNode.data = data;
if (head == null) {
head = newNode;
return;
}
Node current = head;
while (current.next != null) {
current = current.next;
}
current.next = newNode;
}
- 该
insertAfter()
方法在列表中的给定节点之后插入一个新节点。它检查给定的前一个节点是否是null
,如果是则返回。否则,它创建一个新节点,将其data
字段设置为给定数据,并将其next
字段设置next
为前一个节点的字段。然后它将next
前一个节点的字段设置为新节点。
public void insertAfter(Node prevNode, int data) {
if (prevNode == null) {
System.out.println("The given previous node cannot be null.");
return;
}
Node newNode = new Node();
newNode.data = data;
newNode.next = prevNode.next;
prevNode
- 该
deleteNode()
方法从列表中删除一个节点。它首先将一个current
节点设置head
为列表的 ,将一个prev
节点设置为null
。如果该current
节点不是null
并且其data
字段与给定键匹配,则将其设置为该head
节点的LinkedList
节点并返回。否则,它将遍历列表,直到找到具有与给定键匹配的字段的节点,或者直到它到达列表的末尾。如果节点是,则表示在列表中未找到该键,因此它简单地返回。否则,它将节点的字段设置为节点的字段,有效地从列表中删除该节点。next``current``data``current``null``next``prev``next``current``current
public void deleteNode(int key) {
Node current = head;
Node prev = null;
if (current != null && current.data == key) {
head = current.next;
return;
}
while (current != null && current.data != key) {
prev = current;
current = current.next;
}
if (current == null) {
return;
}
prev.next = current.next;
}
- 该
display()
方法显示列表的元素。它只是遍历列表并打印data
每个节点的字段。
public void display() {
Node current = head;
while (current != null) {
System.out.print(current.data + " ");
current = current.next;
}
}
- 该
main()
方法创建一个LinkedList
对象并使用其方法插入、删除和显示列表的元素。
public static void main(String[] args) {
LinkedList list = new LinkedList();
list.insertAtEnd(1);
list.insertAtEnd(2);
list.insertAtEnd(3);
list.insertAtBeginning(0);
list.insertAfter(list.head.next, 1.5);
list.deleteNode(2);
list.display(); // 0 1 1.5 3
}
这是 Java 中链表的基本实现。这些方法可以进一步扩展以包括其他操作,例如使用给定键搜索节点、反转列表等。
-
使用链表的一个优点是它可以动态增长和收缩,这与具有固定大小的数组不同。这意味着我们可以在列表中插入和删除元素,而不用担心空间不足或有未使用的空间。
-
使用链表的另一个优点是我们可以在常数时间 (O(1)) 内插入和删除链表中间的元素,因为我们只需要更新节点之间的链接。相反,在数组中间插入或删除一个元素需要移动所有后续元素,这需要线性时间 (O(n))。
-
使用链表的缺点是节点之间的链接需要额外的内存。相反,数组在内存中连续存储元素,因此它不需要额外的内存来存放指针。
-
此外,通过索引访问链表中的元素很慢,因为我们必须从头遍历列表到所需的索引。相比之下,数组元素可以在常数时间 (O(1)) 内通过它们的索引直接访问。
-
尽管有这些缺点,链表在某些情况下还是很有用的,比如当我们需要一个具有高效插入和删除操作的动态数据结构时。
-
总之,链表是一种由一系列节点组成的数据结构,其中每个节点都包含一个数据字段和指向列表中下一个节点的链接。链表可以动态增长和收缩,并提供高效的插入和删除操作。然而,它们需要额外的内存用于节点之间的链接,并且它们通过索引访问元素的速度很慢。**
本文正在参加「金石计划 . 瓜分6万现金大奖」