題目:
定義乙個函式,輸入乙個鍊錶的頭結點,反轉該鍊錶並輸出反轉後的頭結點。鍊錶定義如下:
struct listnode
;
解題思路:原本我們有乙個這樣的鍊錶,並且知道他的頭結點,即存放數值1的節點的位址。
鍊錶反轉後的效果:
並返回新的鍊錶的頭結點,即原鍊錶最後乙個結點的位址。
為了現實上面的功能,需要調整原煉表中的指標方向,即本來結點2的next要指向結點3的位址,現在將其指向結點1的位址。要完成這個工作需要兩個指標,乙個指標* pnode
指向當前遍歷到的結點,乙個指標* pprev
指向它前乙個結點。
那麼遍歷到結點2時,就像這樣:
此時就出現乙個問題,鍊錶已經斷開了,在原煉表中結點2後面的結點是哪個就不知道了(因為* next
已經指向了結點1),為了避免這個問題,我們需要定義第三個指標* pnext
,用來指向當前的結點的下乙個結點。
剩下的工作就是遍歷原鍊錶,然後調整指標的指向,但是迴圈總需要乙個退出條件,這個條件就是原鍊錶的最後乙個結點的* pnext = null
**實現:
listnode * reverselist(listnode * phead)
pnode->next = pprev;//當前結點的next指向pprev
//對pprev重新賦值,這是因為第一次遍歷鍊錶時pprev一定為null,但是隨著遍歷
//pprev的值總需要跟著變化,相對於下乙個結點而言的前乙個結點就是當前的結點(有點繞)
pprev = pnode;
//和前面一行是一樣的道理,pnode永遠只指向當前的結點,但是在遍歷的過程中,當前的結點
//總要一直在向後移動(要不遍歷什麼呢),所以後移的結點就是pnext,就像之前說的,pnext
//是預先儲存下來的原鍊錶的下乙個結點,因為當我們執行pnode->next = pprev鍊錶就已經斷開了
pnode = pnext;
}return prevesedhead;
}
額,注釋越加越多,要解釋明白這個簡短的**也是挺麻煩的,也說明了這個**的質量確實很高,再貼一些圖說明下吧。
最後需要注意的是while裡面的if判斷,它有兩個作用:
1 如果原鍊錶只有乙個結點的,那麼直接把這個結點位址給預先定義好的反轉後鍊錶的頭結點。
2 如果原鍊錶不只有乙個結點,最終也要進入if,因為遍歷總有結束的時候,這時進入if後會緊跟著退出while。
測試的程式就不貼了,本來這就是個很常見的面試題,有很多資料可以找到完整的測試例程,而且自己寫乙個也不麻煩,在上面只是說下自己的理解。
演算法 反轉鍊錶
編寫帶 實現反轉單鏈表。如 1,2,3,4,5 變為 5,4,3,2,1 要求空間複雜度為o 1 先直接給出乙份完整的 可以直接執行。c include include include typedef int datatype 鍊錶持有的資料的型別 typedef struct node 結點的定義...
演算法 鍊錶反轉
題目 分別實現反轉單向鍊錶和反轉雙向鍊錶的函式。要求如果鍊錶長度為n,時間複雜度要求為o n 額外空間 複雜度要求為o 1 反轉單向鍊錶 class node 反轉單向鍊錶 param head 煉表頭節點 return private static node reverselist node he...
演算法 反轉鍊錶
package bytedance author lzy version 1.0 date 2020 9 4 16 09 反轉鍊錶 public class reverselist public listnode reverselist listnode head 第乙個指標 指向空 翻轉後的末尾節...