反轉單向鏈表

單向鏈表的反轉是一個非常常見的鏈表類面試題,我在刷leetcode的過程中,發現了有許多鏈表題目的解法,都是以反轉鏈表為基礎進行的。所以我覺得有必要記錄一下。

首先先用一張圖來理解單鏈表的反轉。

image
image

單鏈表的反轉,就如上圖一樣,而單鏈表的反轉也有幾種方式,今天我主要是想記錄我用得最頻繁的迭代的方式。

先來看一下鏈表節點的定義:

public class ListNode {
    int val;
    ListNode next;
    ListNode(int x) { val = x; }
}

這就是最基礎的一個鏈表節點,而反轉鏈表的代碼,其實非常的短,關鍵點就在于理解這幾行代碼究竟讓鏈表產生了什么變化。

public ListNode reverseList(ListNode head) {
    ListNode next = null;
    ListNode pre = null

    while (head != null) {
        next = head.next;
        head.next = pre;
        pre = head;
        head = next;
    }
    return pre;
}

我們可以看到四行代碼:

next = head.next; // 1

head.next = pre;  // 2

pre = head;       // 3

head = next;      // 4

第一行代碼:next = head.next;
將head.next賦值給next變量,也就是說next指向了節點2,先將節點2保存起來。

第二行代碼: head.next = pre;
將pre變量賦值給了head.next,即節點1指向了null。

第三行代碼: pre = head;
將head賦值給了pre,即pre指向節點1,將節點1設為“上一個節點”。

第四行代碼:head = next;
將next賦值給head,即head指向了節點2。將節點2設置為“頭結點”。

一次循環的具體過程就是這樣。

所以總結一下單鏈表的反轉:

  • 保存當前頭結點的下個節點。
  • 將當前頭結點的下一個節點指向“上一個節點”,這一步是實現了反轉。
  • 將當前頭結點設置為“上一個節點”。
  • 將保存的下一個節點設置為頭結點。

這樣說起來確實有點拗口,但是我推薦大家在做鏈表類題目和理解鏈表的具體行為時,用一張紙和筆來輔助自己寫寫畫畫,相信很快你就會弄懂鏈表的具體思路的。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容