題目:輸入乙個鍊錶的頭結點,反轉該鍊錶,並返回反轉後鍊錶的頭結點。鍊錶結點定義如下:
struct
listnode
;分析:這是一道廣為流傳的微軟面試題。由於這道題能夠很好的反應出程式設計師思維是否嚴密,在微軟之後已經有很多公司在面試時採用了這道題。
為了正確地反轉乙個鍊錶,需要調整指標的指向。與指標操作相關**總是容易出錯的,因此最好在動手寫程式之前作全面的分析。在面試的時候不急於動手而是一開始做仔細的分析和設計,將會給面試官留下很好的印象,因為在實際的軟體開發中,設計的時間總是比寫**的時間長。與其很快地寫出一段漏洞百出的**,遠不如用較多的時間寫出一段健壯的**。
為了將調整指標這個複雜的過程分析清楚,我們可以借助圖形來直觀地分析。假設下圖中l、m和n是三個相鄰的結點:aß
bß…ßlm
ànà…假設經過若干操作,我們已經把結點l之前的指標調整完畢,這些結點的m_pnext指標都指向前面乙個結點。現在我們遍歷到結點m。當然,我們需要把調整結點的m_pnext
指標讓它指向結點l。但注意一旦調整了指標的指向,鍊錶就斷開了,如下圖所示:aß
bß…lßm
nà…因為已經沒有指標指向結點n,我們沒有辦法再遍歷到結點n了。因此為了避免鍊錶斷開,我們需要在調整m的m_pnext
之前要把n儲存下來。
接下來我們試著找到反轉後鍊錶的頭結點。不難分析出反轉後鍊錶的頭結點是原始鍊錶的尾位結點。什麼結點是尾結點?就是m_pnext為空指標的結點。
基於上述分析,我們不難寫出如下**:
///// reverse a list iteratively
// input: phead - the head of the original list
// output: the head of the reversed head
///listnode* reverseiteratively(listnode* phead)
return preversedhead;
}擴充套件:本題也可以遞迴實現。感興趣的讀者請自己編寫遞迴**。
單向鍊錶的反轉是乙個經常被問到的乙個面試題,也是乙個非常基礎的問題。比如乙個鍊錶是這樣的: 1->2->3->4->5 通過反轉後成為5->4->3->2->1。最容易想到的方法遍歷一遍鍊錶,利用乙個輔助指標,儲存遍歷過程中當前指標指向的下乙個元素,然後將當前節點元素的指標反轉後,利用已經儲存的指標往後面繼續遍歷。源**如下:
struct linka ;還有一種利用遞迴的方法。這種方法的基本思想是在反轉當前節點之前先呼叫遞迴函式反轉後續節點。源**如下。不過這個方法有乙個缺點,就是在反轉後的最後乙個結點會形成乙個環,所以必須將函式的返回的節點的next域置為null。因為要改變head指標,所以我用了引用。演算法的源**如下:void reverse(linka*& head)
head->next = null;
head = pre;
}
linka* reverse(linka* p,linka*& head)else
}
LeetCode 反轉鍊錶(鍊錶問題)
難度 簡單 反轉乙個單鏈表。示例 輸入 1 2 3 4 5 null 輸出 5 4 3 2 1 null使用三個listnode,分別是prev,curr,next。curr是當前指標指向的節點,prev是curr的前乙個節點,頭節點的前乙個節點是null,next是curr的下乙個節點,用於遍歷鍊...
鍊錶的反轉問題
思路 所謂反轉鍊錶就是指將這個鍊錶的所有指標方向反向。採取的辦法是時刻保留連續的3個結點,ppre pcur pnext 修改指標方向 將pcur.next設定為ppre 然後修改ppre pcur pnext向前推進即可 ppre pcur pcur pnext pnext pnext.next ...
鍊錶 反轉鍊錶
問題 兩兩交換鍊錶中的節點 問題 k 個一組翻轉鍊錶 問題鏈結 利用棧先進後出的特性,遍歷鍊錶,將每個結點加入棧中,最後進行出棧操作,先出棧的結點指向臨近的後出棧的結點。definition for singly linked list.struct listnode class solution ...