劍指Offer 翻轉鍊錶

2021-09-05 10:16:32 字數 1864 閱讀 7444

題目:寫出乙個函式,給定乙個鍊錶的頭節點,反轉該鍊錶並輸出其頭節點

struct node

*linklist

對於煉表頭和鍊錶尾,也有多種定義方式。比如:

linklist list;

int value = list-

>value;

//第乙個元素

node *secondnode = list-

>next;

//下乙個節點

node *tail = lastnode;

//假設lastnode為鍊錶最後乙個元素

tail-

>next==

nullptr

;//tail的下乙個節點為空指標

linklist list;

node *firstnode = list-

>next;

//第乙個元素節點

node *tail = lastnode-

>next;

//尾指標為最後乙個節點的下乙個元素

tail-

>next==

nullptr

;

當鍊表為空鍊錶的時候,頭指標的下乙個元素為尾指標。

此題為方便起見,採用第一種定義,煉表頭定義為鍊錶的第乙個節點,尾定義為鍊錶的最後乙個節點。

鍊錶的操作比較複雜,其中包含大量指標操作,稍有不慎就會出錯。為了分析清楚,下邊畫圖來進行分析。

假設a為需要反轉的鍊錶,b為反轉過程進行到c的時候。可以看到,原本c的下乙個元素是d,反轉要求c的下乙個元素指向b,但是如果直接進行操作的話,c和d之間就發生斷裂,再也無法找到d的位址。所以在反轉之前要先儲存d的位址。

同樣地,當鍊表進行到c時,此時由於是單向鍊錶,無法回頭找到b元素的位址,因此在進行到c之前,需要把b的位址儲存下來。

下邊看看鍊錶的首尾如何處理。對於頭結點,其反轉後變為尾節點,其下乙個元素應為空節點,也就是頭結點的mprev設定為空就可以了。

對於尾節點,其下乙個節點為空,因此反轉過程可以進行到某個節點的下個節點為空指標時停止,此時該節點即為頭結點,將其反轉後輸出即可。

實現**如下:

typedef

struct listnode

*linklist;

void

reverselinklist

(linklist &list)

linklist pprev =

nullptr

; linklist pnext =

nullptr

;while

(list-

>next!=

nullptr

) list-

>next = pprev;

}

演算法是直接對輸入的鍊錶進行操作,操作完成後的鍊錶為已經反轉的鍊錶。

首先對輸入進行判斷,如果鍊錶為空指標,則不用反轉直接返回。

如果鍊錶只有1個元素,則也不用反轉,list->next為空,不會程式中的while迴圈,直接返回。

當鍊表元素多於兩個時,對於鍊錶的第乙個節點,先儲存其下乙個節點到pnext,再將list->next設定為mprev,也就是空指標。此時反轉已完成,將自身節點儲存為mprev後,進入下乙個節點。

進入下乙個節點時,會判斷該節點的是否為尾節點,如果不是迴圈一直進行。如果是,則退出迴圈,直接將節點node->next設定為pprev即完成。

反轉鍊錶容易出錯的地方有幾個:

6 劍指offer 翻轉鍊錶

class solution 如果head為null的時候,pre就為最後乙個節點了,但是鍊錶已經反轉完畢,pre就是反轉後鍊錶的第乙個節點 直接輸出pre就是我們想要得到的反轉後的鍊錶 return pre 第二種方法是 遞迴方法 struct listnode class solution 2 ...

劍指Offer16翻轉鍊錶

題目 定義乙個函式,輸入乙個鍊錶的頭結點,翻轉該鍊錶並輸出翻轉後鍊錶的頭結點。分析 這個題剛看的時候可能會和之前遇到的逆序輸出鍊錶差不多,不過在那個題目中並沒有改變鍊錶的指標,而是通過增加空間來進行逆序輸出的,還記得怎麼做嗎?當然就是增加乙個n長度的棧。當然如果題目要求中是可以改變鍊錶的,並且只允許...

劍指Offer 16 翻轉鍊錶

題目 定義乙個函式,輸入乙個鍊錶的頭結點,翻轉該鍊錶並輸出翻轉後的鍊錶。思路 1.使用兩個指標a,b分別指向待翻轉的兩個結點,同時為了防止斷鏈,使用乙個指標c儲存b next指標,c b next。2.a,b兩個結點翻轉後,令a b,b c。3.迴圈1,2直至b為null。注意 1.頭結點的next...