在 Java 中,链表是一种常见的数据结构,它由一系列节点组成,每个节点包含数据和指向链表中下一个节点的引用。链表不同于数组,它不要求在内存中连续存储,这使得链表在内存分配和动态扩展方面更加灵活。
基础概念
节点(Node)
链表中的每个节点包含两个主要元素:数据(通常称为“值”)和指向链表中下一个节点的引用(也称为“指针”或“链接”)。在 Java 中,节点通常是一个自定义的类实例。
class Node {int data;Node next;public Node(int data) {this.data = data;this.next = null;}
}
单向链表
单向链表是最简单的链表类型,其中每个节点只包含指向下一个节点的引用。
双向链表
双向链表每个节点除了包含指向下一个节点的引用外,还包含一个指向前一个节点的引用。
循环链表
循环链表是一种特殊的链表,其中最后一个节点的“下一个”引用指向第一个节点,形成一个环。
常用方法
创建链表
public class LinkedListExample {public static void main(String[] args) {Node head = new Node(1);head.next = new Node(2);head.next.next = new Node(3);head.next.next.next = new Node(4);}
}
遍历链表
public void printList(Node node) {while (node != null) {System.out.print(node.data + " ");node = node.next;}System.out.println();
}
查找节点
public Node find(Node head, int key) {Node current = head;while (current != null) {if (current.data == key) {return current;}current = current.next;}return null;
}
插入节点
public void insertAtBeginning(Node newNode) {newNode.next = head;head = newNode;
}
删除节点
public void deleteNode(Node head, int key) {if (head == null) {return;}if (head.data == key) {head = head.next;return;}Node current = head;while (current.next != null) {if (current.next.data == key) {current.next = current.next.next;return;}current = current.next;}
}
反转链表
public Node reverseList(Node head) {Node prev = null;Node current = head;Node next = null;while (current != null) {next = current.next;current.next = prev;prev = current;current = next;}return prev;
}
查找中间节点
public Node findMiddleNode(Node head) {if (head == null) {return null;}Node slow = head;Node fast = head;while (fast != null && fast.next != null) {slow = slow.next;fast = fast.next.next;}return slow;
}
完整示例
下面是一个完整的 Java 链表示例,包括创建、遍历、插入、删除和反转链表的方法。
public class LinkedListExample {public static void main(String[] args) {LinkedListExample list = new LinkedListExample();list.insertAtBeginning(new Node(1));list.insertAtBeginning(new Node(2));list.insertAtBeginning(new Node(3));System.out.println("原始链表:");list.printList(list.head);list.deleteNode(list.head, 2);System.out.println("删除节点 2 后的链表:");list.printList(list.head);list.head = list.reverseList(list.head);System.out.println("反转后的链表:");list.printList(list.head);}Node head;public void insertAtBeginning(Node newNode) {newNode.next = head;head = newNode;}public void printList(Node node) {while (node != null) {System.out.print(node.data + " ");node = node.next;}System.out.println();}public void deleteNode(Node head, int key) {if (head == null) {return;}if (head.data == key) {head = head.next;return;}Node current = head;while (current.next != null) {if (current.next.data == key) {current.next = current.next.next;return;}current = current.next;}}public Node reverseList(Node head) {Node prev = null;Node current = head;Node next = null;while (current != null) {next = current.next;current.next = prev;prev = current;current = next;}return prev;}
}
在这个例子中,我们创建了一个 `LinkedListExample` 类,它包含一个 `head` 属性来存储链表的头节点。我们定义了几个方法来操作链表,包括插入节点到链表的开始、打印链表、删除节点和反转链表。
总结
Java 中的链表是一种灵活且常用的数据结构,适用于需要动态内存分配和扩展的场景。通过使用节点和引用,链表可以在内存中以非连续的方式存储数据,这使得它在处理大量数据时比数组更加高效。在实际应用中,理解和掌握链表的相关操作对于解决各种问题非常重要。通过练习和实际应用,你可以更好地理解链表的工作原理和如何在 Java 中有效地使用它们。