理解單鏈表的反轉(java實現)


理解單鏈表的反轉(java實現)

要求很簡單,輸入一個鏈表,反轉鏈表后,輸出新鏈表的表頭。
  反轉鏈表是有2種方法(遞歸法,遍歷法)實現的,面試官最愛考察的算法無非是斐波那契數列和單鏈表反轉,遞歸方法實現鏈表反轉比較優雅,但是對於不了解遞歸的同學來說還是有理解難度的。

遞歸法


總體來說,遞歸法是從最后一個Node開始,在彈棧的過程中將指針順序置換的。
遞歸法實現圖

為了方便理解,我們以 1->2->3->4這個鏈表來做演示。輸出的效果是4->3->2->1

首先定義Node:

public static class Node {
	public int value;
	public Node next;

	public Node(int data) {
		this.value = data;
	}
}

反轉方法如下:

public Node reverse(Node head) {
    if (head == null || head.next == null)
        return head;
    Node temp = head.next;
    Node newHead = reverse(head.next);
    temp.next = head;
    head.next = null;
    return newHead;
}

遞歸實質上就是系統幫你壓棧的過程,系統在壓棧的時候會保留現場。

我們來看是怎樣的一個遞歸過程:1->2->3->4

  • 程序到達Node newHead = reverse(head.next);時進入遞歸
  • 我們假設此時遞歸到了3結點,此時head=3結點,temp=3結點.next(實際上是4結點)
  • 執行Node newHead = reverse(head.next);傳入的head.next是4結點,返回的newHead是4結點。
  • 接下來就是彈棧過程了
    • 程序繼續執行 temp.next = head就相當於4->3
    • head.next = null 即把3結點指向4結點的指針斷掉。
    • 返回新鏈表的頭結點newHead

注意:當retuen后,系統會恢復2結點壓棧時的現場,此時的head=2結點;temp=2結點.next(3結點),再進行上述的操作。最后完成整個鏈表的翻轉。

遍歷法


遍歷法就是在鏈表遍歷的過程中將指針順序置換
enter image description here
先上代碼:

public static Node reverseList(Node node) {
	Node pre = null;
	Node next = null;
	while (node != null) {
		next = node.next;
		node.next = pre;
		pre = node;
		node = next;
	}
	return pre;
}

依舊是1->2->3->4

  • 准備兩個空結點 pre用來保存先前結點、next用來做臨時變量
  • 在頭結點node遍歷的時候此時為1結點
    • next = 1結點.next(2結點)
    • 1結點.next=pre(null)
    • pre = 1結點
    • node = 2結點
  • 進行下一次循環node=2結點
    • next = 2結點.next(3結點)
    • 2結點.next=pre(1結點)=>即完成2->1
    • pre = 2結點
    • node = 3結點
  • 進行循環...


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM