链表
1.链表类
class ListNode {
int val;
ListNode next;
ListNode(){}
ListNode(int val){this.val = val;}
ListNode(int val, ListNode next){this.val = val;this.next = next;}
}
2.创建链表
(1)逐个节点创建
这是最基本的方法,逐个创建链表节点,并通过指针连接它们。这种方法可以灵活地控制每个节点的值和连接关系。
// 例如链表:1->2->3->...
ListNode head = new ListNode(1);
head.next = new ListNode(2);
head.next.next = new ListNode(3);
// 继续添加节点...
(2)使用循环创建
可以使用循环来简化逐个节点创建的过程,特别是在已知节点值的情况下,循环遍历值数组来创建链表节点。
int[] values = {1, 2, 3};
ListNode dummy = new ListNode(0); // 创建一个虚拟头节点
ListNode tail = dummy;
for (int val : values) {
ListNode newNode = new ListNode(val);
tail.next = newNode;
tail = newNode;
}
ListNode head = dummy.next;
(3)头插法
头插法是一种创建链表的方法,在遍历元素的同时,将新节点插入到链表头部。
int[] values = {1, 2, 3};
ListNode dummy = new ListNode(0); // 创建一个虚拟头节点
for (int val : values) {
ListNode newNode = new ListNode(val);
newNode.next = dummy.next;
dummy.next = newNode;
}
ListNode head = dummy.next;
(4)尾插法
尾插法是一种创建链表的方法,在遍历元素的同时,将新节点插入到链表尾部。
int[] values = {1, 2, 3};
ListNode dummy = new ListNode(0); // 创建一个虚拟头节点
ListNode tail = dummy;
for (int val : values) {
ListNode newNode = new ListNode(val);
tail.next = newNode;
tail = newNode;
}
ListNode head = dummy.next;
3.关于链表的题目
(1)LeetCode203. 移除链表元素
public class 移除链表元素 {
public static void main(String[] args) {
// 初始化链表的元素值数组和要移除的值
int[] nums = {1, 2, 6, 3, 4, 5, 6};
int val = 6;
// 创建一个虚拟头节点和尾节点
ListNode dummy = new ListNode();
ListNode tail = dummy;
// 遍历元素值数组,创建链表
for (int num : nums) {
ListNode newNode = new ListNode(num);
tail.next = newNode;// 将新节点连接到链表尾部
tail = newNode;// 更新尾节点
}
// 获取链表的头节点
ListNode head = dummy.next;
// 调用移除元素函数
ListNode res = removeElements(head, val);
// 输出移除后的链表结果
while (res != null) {
System.out.print(res.val + " ");
res = res.next;
}
}
// 移除链表中值为val的元素
public static ListNode removeElements(ListNode head, int val) {
// 创建一个虚拟头节点,并将其next指向原链表的头节点
ListNode res = new ListNode();
res.next = head;
// 创建一个指针ptr,初始指向虚拟头节点
ListNode ptr = res;
// 遍历链表,移除值为val的节点
while (ptr.next != null) {
if (ptr.next.val == val) {
ptr.next = ptr.next.next;// 跳过当前节点,将下一个节点连接到当前节点的前一个节点
} else {
ptr = ptr.next;// 移动指针到下一个节点
}
}
return res.next;// 返回移除元素后的链表
}
}
(2)LeetCode237. 删除链表中的节点
public void deleteNode(ListNode node) {
node.val = node.next.val;
node.next = node.next.next;
}
(3)LeetCode206. 反转链表
// 迭代方法反转链表
public static ListNode reverseList(ListNode head) {
if (head == null || head.next == null) {
return head; // 如果链表为空或只有一个节点,直接返回该节点
}
ListNode prev = null;
ListNode curr = head;
while (curr != null) {
ListNode nextTemp = curr.next;// 保存当前节点的下一个节点
curr.next = prev;// 当前节点的指针指向前一个节点
prev = curr; // 前一个节点移动到当前节点
curr = nextTemp; // 当前节点移动到下一个节点
}
return prev; // prev成为了新的头节点
}