看一遍就理解,圖解單鏈表反轉

前言

反轉鏈表是程序員必備的基本素養,常常在面試、筆試的過程當中出現。一直以爲反轉鏈表實現代碼不是很好理解,決定搬leetcode那道經典反轉鏈表題出來,用十多張圖去解析它,但願加深你們對鏈表反轉的理解,謝謝閱讀。程序員

leetcode的反轉鏈表原題&答案

題目描述: 反轉一個單鏈表。面試

輸入: 1->2->3->4->5->NULL
輸出: 5->4->3->2->1->NULL
複製代碼

分析:bash

假設存在鏈表 1 → 2 → 3 → Ø,咱們想要把它改爲 Ø ← 1 ← 2 ← 3。學習

在遍歷列表時,將當前節點的 next 指針改成指向前一個元素。因爲節點沒有引用其上一個節點,所以必須事先存儲其前一個元素。在更改引用以前,還須要另外一個指針來存儲下一個節點。不要忘記在最後返回新的頭引用!ui

代碼實現:spa

public ListNode reverseList(ListNode head) {  
    ListNode prev = null;   
    ListNode curr = head;   
    while (curr != null) {  
        ListNode nextTemp = curr.next;
        curr.next = prev;
        prev = curr;
        curr = nextTemp;
    }
    return prev;
}
複製代碼

圖解鏈表反轉代碼的實現

接下來,咱們圖解以上代碼實現,先對以上實現代碼加上行號,以下:3d

public ListNode reverseList(ListNode head) {  //1
    ListNode prev = null;   // 2
    ListNode curr = head;   // 3
    while (curr != null) {   //4
        ListNode nextTemp = curr.next; //5
        curr.next = prev;  // 6 
        prev = curr;  //7
        curr = nextTemp; //8
    } 
    return prev;  //9
}
複製代碼

第一行代碼圖解

public ListNode reverseList(ListNode head) {  //1
複製代碼

咱們順着題目描述意思,假設鏈表就有一、二、3個元素吧,後面還跟着一個null,又由於輸入是ListNode head,因此這個即將要反轉的鏈表以下:指針

第二行代碼圖解

ListNode prev = null;   // 2
複製代碼

將null賦值給prev,即prev指向null,可得圖以下: code

第三行代碼圖解

ListNode curr = head;
複製代碼

將鏈表head賦值給curr,即curr指向head鏈表,可得圖以下:cdn

循環部分代碼圖解

while (curr != null) {   //4
        ListNode nextTemp = curr.next; //5
        curr.next = prev;  // 6 
        prev = curr;  //7
        curr = nextTemp; //8
    }
複製代碼

循環部分是鏈表反轉的核心部分,咱們先走一遍循環,圖解分析一波。

由於curr指向了headhead不爲null,因此進入循環。先來看第5行:

ListNode nextTemp = curr.next; //5
複製代碼

把curr.next 賦值給nextTemp變量,即nextTemp 指向curr的下一節點(即節點2),可得圖以下:

再執行到第6行:

curr.next = prev;  // 6 
複製代碼

把prev賦值給curr.next,由於prev初始化化指向null,即curr(節點1)指向了null,鏈表圖解成這樣了:

而後咱們看執行到第7行

prev = curr;  //7
複製代碼

把curr賦值給prev,prev指向curr,圖解以下:

接着,咱們執行到第8行:

curr = nextTemp; //8
複製代碼

把nextTemp賦值給curr,即curr指向nextTemp,圖解以下:

至此,第一遍循環執行結束啦,回到循環條件,curr依舊不爲null,咱們繼續圖解完它。

5-8行代碼又執行一遍,依次可得圖:

ListNode nextTemp = curr.next; //5
        curr.next = prev;  // 6 
        prev = curr;  //7
        curr = nextTemp; //8
複製代碼

執行完ListNode nextTemp = curr.next;後:

執行完curr.next = prev;後:

執行完prev = curr;後:

執行完curr = nextTemp;後:

來到這裏,發現curr仍是不爲null,再回到while循環,再執行一遍:

ListNode nextTemp = curr.next; //5
        curr.next = prev;  // 6 
        prev = curr;  //7
        curr = nextTemp; //8
複製代碼

依次可得圖:

來到這裏,咱們發現curr已經爲null了,能夠跳出循環了。這時候prev指向的就是鏈表的反轉呀,因此第9行執行完,反轉鏈表功能實現:

return prev;  //9
複製代碼

參考與感謝

我的公衆號

  • 若是你是個愛學習的好孩子,能夠關注我公衆號,一塊兒學習討論。
  • 若是你以爲本文有哪些不正確的地方,能夠評論,也能夠關注我公衆號,私聊我,你們一塊兒學習進步哈。
相關文章
相關標籤/搜索