如何在Java中就地反转一个单链表且不需要额外内存?
我正在用Java实现一个自定义的单向链表,用于一个项目,需要实现一个反转链表的方法。主要约束是必须就地完成(空间复杂度O(1)),也就是说只能操作现有节点的指针。
我的当前方法: 我正在尝试使用三个指针(prev、current 和 next),但在过程末尾正确重新分配 head 和 tail 以避免引用丢失时遇到了困难。
最小可复现示例:
public void reverseInPlace() {
// Edge case: Empty list or single-node list doesn't need scaling/reversing
if (head == null || head.getNext() == null) {
return;
}
Node prev = null;
Node current = head;
Node next = null;
tail = head; // The original head safely becomes the new tail
while (current != null) {
next = current.getNext();
current.setNext(prev);
prev = current;
current = next;
}
head = prev;
}
问题: 虽然这段逻辑在3 个及以上节点的列表上似乎可行,但我担心边界情况。在Java中处理空列表或单节点列表时,这是否是处理空指针的标准做法?这种指针重新分配是否可能导致内存泄漏?
解决方案
你的方法
public void reverseInPlace() {
Node prev = null;
Node current = head;
Node next = null;
tail = head; // The original head becomes the new tail
while (current != null) {
next = current.getNext();
current.setNext(prev);
prev = current;
current = next;
}
head = prev;
}
是正确的。情形如下:
1.链表为空,head和 tail都为null
Tail被设为head,while被跳过,head被设为prev。由于三者都为null,因此不会有问题。
2.链表恰好只有一个元素
Tail被设为head,我们进入while正好一次,在这次循环中,head的 next被设为null,prev被设为当前节点,也就是head,循环结束后,head实际上等于它自己。
3.链表至少有两个元素
3.1.头节点
它的next被设为null,随后继续处理之前提取的原下一个元素,以免丢失对下一个元素的引用。
3.2.中间元素
它将next指向前一个元素,然后继续处理之前提取的原下一个元素,以防丢失对下一个元素的引用。
3.3.曾经的尾部
它的next被设为前一个元素,while循环结束。
3.4. while之前和之后
tail已被设为它的最终值,head将成为最后一个prev,即原尾节点。
然而,即便是正确的,在情况简单的情况下进行赋值并检查while条件也没有意义。想象一个空链表或只有一个元素的链表。在这种情况下,你不需要进行赋值。因此只有在链表至少有两个元素的条件下再这么做才有意义,例如:
public void reverseInPlace() {
if (head != tail) {
Node prev = null;
Node current = head;
Node next = null;
tail = head; // The original head becomes the new tail
while (current != null) {
next = current.getNext();
current.setNext(prev);
prev = current;
current = next;
}
head = prev;
}
}
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。