反轉鏈表

扯淡

以前據說過google面試反轉鏈表的梗,也嘗試着本身實現了一次,算是比較簡單的問題。但在紙上手寫代碼的時候,思惟就很亂,多是隔的時間長忘記了,或者以前就跟本沒有理清思路,因此被虐的很慘。
這篇文章的目的就是梳理一下思路,加深印象。若是有更好的算法,留言求虐啊~java


描述

這是一個普通的鏈表,由ABCD4個節點組成,每一個節點都包含數據區-data和指向下一個節點的引用-next
鏈表node

反轉鏈表,顧名思義就是將鏈表每一個節點的next引用反過來,如ABCD,變爲DCBA。固然,前提是咱們只持有頭節點的引用,且稱爲Node a,那麼鏈表反轉後的頭節點,就是Node d。面試

分析

要將此鏈表反轉,咱們核心的需求是:修改每個節點的next引用,將next指向前一個節點,將原來的頭節點A中的next,指向null算法

既然每個節點都須要操做,那就考慮循環吧,設一個索引(或者稱爲遊標)node(能夠利用節點A的引用),從節點A跑到節點D,當它再日後移動指向null時,循環結束。那麼循環邊界條件則爲google

while(node != null){
//do something
}

而後咱們再看看每一個節點作一次反轉(即每次循環),都須要作什麼事情spa

  1. 在修改當前節點的next引用以前,要先保存其值,爲了不丟失下一個節點(即Node next)的引用。3d

  2. 進行反轉,修改當前節點的next,使之指向上一個節點(即Node lastcode

  3. 要保存當前節點的引用,爲了提供給下一次循環時,對下個節點進行反轉blog

  4. 爲了保證while循環能夠從頭節點A遍歷到尾節點D,那麼遊標node在循環體最後要向後移動一個節點,即指向下一個節點。索引

代碼

Node reversalLinkedList(Node node){
    Node last = null;
    Node next = null;
    while(node != null){
        next = node.getNext();//1 拿到下個節點的引用,爲了提供給第4步使node向鏈表後方移動
        node.setNext(last);//2 將當前節點指向上一個節點
        last = node;//3 將last指向當前節點,提供給下次循環的第2步
        node = next;//4 將當前節點的引用(即遊標)指向下一個節點        
    }
    /*
    * 循環完成後,node和next都指向了原節點D的next指向的位置,即null
    * 而last指向了上述null前面的位置,即節點D
    * 將last返回,則獲得鏈表ABCD反轉後鏈表DCBA的頭節點D
    */
    return last;
}

邏輯其實很簡單,須要注意的就是每次循環時須要暫存的引用 -- next,last

圖解

每次循環其實就是修改當前節點next的引用+三個引用(last,node,next)的後移,以下圖

第一次循環前
第一次循環前
第一次循環的過程
第一次循環時
第一次循環結束後
第一次循環結束後

最後所有反轉後
圖片描述

總結

  1. 保存當前節點,上一個節點,下一個節點的引用

  2. 每次循環最後,當前節點向後移動

相關文章
相關標籤/搜索