单链表反转(JAVA)
单链表主类
public class SinglyLinkedList<T> {
private SinglyLinkedNode<T> header;
private int size;
private static final int MAX = 5;
public SinglyLinkedNode<T> getHeader() {
return header;
}
public void setHeader(SinglyLinkedNode<T> header) {
this.header = header;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
class SinglyLinkedNode<T> {
private T data;
private SinglyLinkedNode<T> next;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public SinglyLinkedNode<T> getNext() {
return next;
}
public void setNext(SinglyLinkedNode<T> next) {
this.next = next;
}
public SinglyLinkedNode(T data) {
this.data = data;
}
}
}
单链表反转思路
单链表反转,类似徒步行军过程中,执行如下命令:“全体注意,向后转,队首变队尾,跑步前进!”
最终目的是原header
变为了新tail
,其next
为null
;原tail
则变为新header
。
仍以徒步行军队伍向后转为例
从单链表的方向来看,单链表的header
将会是队尾那位战士
执行步骤是:从header
(队尾那位战士)开始,逐个向后转
重点在于每一位战士向后转时所做的必要操作。结合单链表来说,新转身的战士,将是新的header
,而且他的next
将指向原header
;与此同时,需要暂存该战士转身前的原next
,方便找到下一个要转身的战士,即current
过程大致如下:
需要四步
- 暂存
current.getNext()
,即后半截,一系列操作后会把它赋值给current
并进入下一轮 - 将
current
的next
设置为header,这里做相邻的转向 - 重新设定
header
,新的header
就是当前的current
- 将暂存的后半截赋值给
current
,本轮结束,进入下一轮
图解
代码
public void reverse() {
// 边界
if (header == null) {
return;
}
SinglyLinkedNode<T> current = header;
while (current != null) {
// 1
SinglyLinkedNode<T> temp = current.getNext();
// 2 边界
if (current == header) {
current.setNext(null);
} else {
current.setNext(header);
}
// 3
header = current;
// 4
current = temp;
}
}
2019-03-15 再来看这段代码,觉得header
的处理可以放在while
外边,这样不至于在循环体里每次都做一次current
判头操作
public void reverse() {
// 边界
if (header == null) {
return;
}
// 循环reverse直接从第二个节点开始
SinglyLinkedNode<T> current = header.getNext();
// 先处理头
header.setNext(null);
while (current != null) {
// 1
SinglyLinkedNode<T> temp = current.getNext();
// 2 边界
current.setNext(header);
// 3
header = current;
// 4
current = temp;
}
}