鍊錶反轉一般有兩種解法:遞迴和迭代。首先給出鍊錶的定義
typedef struct taglnode linklist;
假設鍊錶為head->1->2->3->4->5->null。
linklist * reverse(linklist *head)
一開始我的想法是,先遞迴到最後一層,也就是reverse(5),這層的執行結果是返回5號結點給上層的temp,那麼我們回到了第四層:head就是4號結點,temp是5號。讓temp的後續變成head不行嗎?在這一層是可以的。那麼我們再回到第三層,head是3號結點,temp是5號結點(請注意,後續為4號結點),再執行temp->next=head時,5號結點的後續又變為3號,問題來了,程式好像在打轉。所以問題在於我們返回的temp永遠是5號結點,不能更改temp的後繼。正確做法是head->next->next = head,每層發生的事情與temp無關,它只負責返回5號結點。
這裡想說說遞迴的缺點:首先遞迴存在重複計算(參考斐波那契數列),而且每次遞迴都是一次函式呼叫,每次呼叫都需要在記憶體棧中分配空間來儲存引數、返回位址和臨時變數,這就導致了彈棧入棧的時間消耗。遞迴還可能導致呼叫棧溢位:每個程序棧的容量是有限的,呼叫層級太多就會超出棧的容量,導致呼叫棧溢位。
linklist * reverse(linklist *head)
linklist *next = p->next;//後繼結點
while (next)
p->next = prev;//最後的乙個結點手動指向prev
return p;//返回最後乙個結點,也是新鍊錶的頭結點
}
迭代法的好處就是簡單易懂:由於每次迴圈會斷開p與原始後繼的鍊子,需要用next指標來儲存後繼結點,然後就是迴圈呼叫p->next=prev,移動這三個結點即可。
我總以為自己理解的鍊錶的操作,可是隔一段時間就忘了,可能是沒有深入分析。另外這是我的第一篇部落格,也是被一位大佬鼓動,加油吧!
資料結構之單鏈表反轉
單鏈表反轉的非遞迴方法 首先是結點的定義 public class node 使用非遞迴方法反轉單鏈表,需要設定兩個node型別的物件pre和nex,pre用來記錄head的前乙個結點,nex用來記錄head的後乙個結點,然後講head結點後移。public node reversecur node...
資料結構 單鏈表實現反轉
如果鍊錶只有乙個或者沒有節點,則無需反轉 原鍊錶的第乙個節點即為反轉後的最後乙個元素,需要將其固定,我們叫它final 按原鍊錶的順序從第二個開始對所有節點node進行遍歷,每次將final的next重新指向node的next,將node的next重新指向head的next,將head的next重新...
資料結構 手撕單鏈表反轉
引言 今天面美團上來讓手撕單鏈表反轉,心中暗自竊喜,這麼簡單的演算法,能到今天要起飛了嗎,結果在牛客面試沒給題目介面,讓自己實現單鏈表,頓時心生畏懼,最近一直刷演算法,實現單鏈表這不是鬧呢嗎,哎,結果可想而知,面試官說我基礎不夠紮實,現在咱還是乖乖實現乙個打打基礎吧。演算法思想 思路其實很簡單,儲存...