劍指Offer(Java版):反轉鏈表

題目:定義一個函數,輸入一個鏈表的頭結點,反轉該鏈表並輸出反轉後鏈表的頭結點。面試

解決與鏈表相關的問題老是有大量的指針操做,而指針操做的代碼老是容 易出錯的。不少的面試官喜歡出鏈表相關的問題,就是想經過指針操做來考察應聘者的編碼功底。爲了不出錯,咱們最好先進行全面的分析。在實際軟件開發週期 中,設計的時間一般不會比編碼的時間短。在面試的時候咱們不要急於動手寫代碼,而是一開始仔細分析和涉及,這將會給面試官留下好的印象。與其給出一段漏洞 百出的代碼,倒不如仔細分析再寫出魯棒性好的代碼。函數

爲了正確的反轉一個鏈表,須要調整鏈表中指針的方向。爲了將調整指針 這個複雜的過程分析清楚,咱們能夠藉助圖形來直觀的分析。在圖中所示的鏈表中,h,i,j是3個相鄰的結點。假設通過若干的操做,咱們已經把結點h以前的 指針調整完畢,這些結點的m_pNext都指向前面的一個結點。接下來咱們把i的m_pNext指向h,此時的鏈表結構如圖b所示。編碼

不難注意到,因爲結點i的m_pNext指向了它的前一個結點,致使咱們沒法在鏈表中遍歷到結點j。爲了不鏈表在結點i處斷開,咱們須要在調整結點i的m_pNext以前,把結點j保存下來。spa

也就是說咱們在調整結點i的m_pNext指針時,除了須要知道結點 i自己以外,還須要i的前一個結點h,由於咱們須要把結點i的m_pNext指向結點h,同時,咱們還實現須要保存i個結點j,以防止鏈表斷開。所以相應 地咱們須要三個指針,分別指向當前遍歷到的結點,它的前一個結點和後一個結點。設計

最後咱們試着找到反轉鏈表的頭結點。不難分析出反轉後的鏈表的頭結點是原始鏈表的尾節點。什麼結點是尾節點,天然是m_pNext爲 Null 的結點。指針

分析寫出下面的代碼:遞歸

package cglib;
class ListNode
{
   int data;
   ListNode nextNode;
}開發

public class DeleteNode {
    public static void main(String[] args) {
        ListNode head=new ListNode();
        ListNode second=new ListNode();
        ListNode third=new ListNode();
        ListNode forth=new ListNode();
        head.nextNode=second;
        second.nextNode=third;
        third.nextNode=forth;
        head.data=1;
        second.data=2;
        third.data=3;
        forth.data=4;
        DeleteNode test=new DeleteNode();
        ListNode resultListNode=test.reverseList(head);
        System.out.println(resultListNode.data);
        }
    public ListNode reverseList(ListNode head){
        if(head == null)  
            return null;  
        ListNode preListNode = null;  
        ListNode nowListNode = head;  
          
        while(nowListNode != null){ //1->2->3->4
            ListNode nextListNode = nowListNode.nextNode;   //保存下一個結點2  
            nowListNode.nextNode = preListNode;  //當前結點指向前一個結點null<-1
            preListNode = nowListNode;                  //前任結點 等於現任節點 null<-1<-2
            nowListNode = nextListNode;                 //現任節點等於下一結點  null<-1<-2,而後從2開始循環,直至preListNode=4,nowListNode=null
        }  
        return preListNode;  
        }
}class


輸出 4test

 

拓展: 遞歸實現一樣的反轉鏈表的功能。

public ListNode reverseList(ListNode head){         if(head==null || head.nextNode==null)               return head;           else           {  //1->2->3->4                          ListNode nextNode = head.nextNode; //2             head.nextNode = null; //null<-1             ListNode reverseRest = reverseList(nextNode); //從2開始遞歸             nextNode.nextNode = head;  //3<-4             return reverseRest;           }       }

相關文章
相關標籤/搜索