據說單鏈表反轉問題面試中經常問,而鏈表這個東西相對於數組的確稍微難想象,因此今天紀錄一下單鏈表反轉的代碼。
1,先定義一個節點類。
1 public class Node { 2 int index; 3 Node next; 4 5 public Node(int index, Node next) { 6 this.index = index; 7 this.next = next; 8 } 9 }
2,我一共寫了三種方法
(1)迭代法。先將下一節點紀錄下來,然后讓當前節點指向上一節點,再將當前節點紀錄下來,再讓下一節點變為當前節點
public Node reverse(Node node) { Node prev = null; Node now = node; while (now != null) { Node next = now.next; now.next = prev; prev = now; now = next; } return prev; }
(2)遞歸方法1。先找到最后一個節點,然后從最后一個開始反轉,然后當前節點反轉時其后面的節點已經進行反轉了,不需要管。最后返回原來的最后一個節點
public Node reverse2(Node node, Node prev) { if (node.next == null) { node.next = prev; return node; } else { Node re = reverse2(node.next, node); node.next = prev; return re; } }
(3)遞歸方法2。先找到最后一個節點,然后從最后一個節點之前的那個節點的方法體中開始將下一個指向當前一個,然后當前節點反轉時其后面的節點已經進行反轉了,不需要管。最后返回原來的最后一個節點。
public Node reverse3(Node node) { if(node.next==null)return node; Node next = node.next; node.next = null; Node re = reverse3(next); next.next = node; return re; }
總結:迭代法思路很清晰,就是將當前節點和下一節點保存起來,然后將當前節點反轉;遞歸法1是先找到最后一個節點進行反轉,然后再反轉之前的節點時就不用擔心丟失以后的節點了,只需要關心本節點的反轉;遞歸法2是同理,只是反轉動作是從最后一個節點的前一個節點開始的。另外這幾個方法都沒有考慮首節點為null的情況,切記。