面經------單向鏈表反轉

面經------單向鏈表反轉

問題描述

現定義瞭如下的ListNode結構, 要求對整個List進行反轉。

//Definition for singly-linked list.
public class ListNode {
      int val;
      ListNode next;
      ListNode(int x) { val = x; }
}

遞歸解法

遞歸的思路是從鏈表的最後一個Node開始反轉,創建一個newHead指向最後一個Node(cur),head指向newHead的前一個Node, 然後反轉cur和head,如此逐步向前。

詳細解釋如下。

首先指針H迭代到底如下圖所示,並且設置一個新的指針newHead作爲反轉後的鏈表的頭。由於整個鏈表翻轉之後的頭就是最後一個數,所以整個過程newHead指針一直指向最後一個Node。

然後H指針逐層返回的時候如下圖,將H指向的地址賦值給nextNode->next指針,並且一定要記得讓H->next =NULL,也就是斷開現在指針的鏈接,否則新的鏈表形成了環,下一層nextNode->next賦值的時候會覆蓋後續的值。程序中的nextNode指針即爲上一層返回的H->next.

第二次返回nextNode後如下圖。

逐層返回:

返回到頭後如下圖:

代碼如下:

public ListNode reverseList(ListNode head) {
        if(head == null || head.next == null)
            return head;
        ListNode nextNode = head.next;
        ListNode newHead = reverseList(nextNode);
        nextNode.next = head;
        head.next = null;
        return newHead;
        }

非遞歸解法

非遞歸的方法與遞歸方法相反,它是從前往後順序處理Node的。

首先設置兩個新Node,P (curr)和 newH(prev)。

然後依次將舊鏈表上每一項添加在新鏈表的後面,然後新鏈表的頭指針NewH移向新的鏈表頭,如下圖所示。此處需要注意,不可以上來立即將上圖中P->next直接指向NewH,這樣存放2的地址就會被丟棄,後續鏈表保存的數據也隨之無法訪問。而是應該設置一個臨時指針nextTemp,先暫時指向P->next指向的地址空間,保存原鏈表後續數據。然後再讓P->next指向NewH,最後P=nextTemp就可以取回原鏈表的數據了,所有循環訪問也可以繼續展開下去

指針繼續向後移動,直到P指針指向NULL停止迭代。

最後一步

代碼如下:

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;
}

僅用於個人的學習理解,如需轉載,請標明出處:
https://blog.csdn.net/sc19951007/article/details/83613598

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章