資料結構和演算法設計專題之 單鏈表的逆序

2022-08-16 22:51:15 字數 2048 閱讀 7107

下面來看一下很經典的「單鏈表逆序」問題。很多公司的面試題庫中都有這道題,有的公司明確題目要求不能使用額外的節點儲存空間,有的沒有明確說明,但是如果面試者使用了額外的節點儲存空間做中轉,會得到乙個比較低的分數。如何在不使用額外儲存節點的情況下使乙個單鏈表的所有節點逆序?我們先用迭代迴圈的思想來分析這個問題,鍊錶的初始狀態如圖(1)所示:

圖(1)初始狀態

初始狀態,prev是null,head指向當前的頭節點a,next指向a節點的下乙個節點b。首先從a節點開始逆序,將a節點的next指標指向prev,因為prev的當前值是null,所以a節點就從鍊錶中脫離出來了,然後移動head和next指標,使它們分別指向b節點和b的下乙個節點c(因為當前的next已經指向b節點了,因此修改a節點的next指標不會導致鍊錶丟失)。逆向節點a之後,鍊錶的狀態如圖(2)所示:

圖(2)經過第一次迭代後的狀態

從圖(1)的初始狀態到圖(2)狀態共做了四個操作,這四個操作的偽**如下:

head->next = prev;

prev = head;

head = next;

next = head->next;

這四行偽**就是迴圈演算法的迭代體了,現在用這個迭代體對圖(2)的狀態再進行一輪迭代,就得到了圖(3)的狀態:

圖(3)經過第二次迭代後的狀態

那麼迴圈終止條件呢?現在對圖(3)的狀態再迭代一次得到圖(4)的狀態:

圖(4)經過第三次迭代後的狀態

此時可以看出,在圖(4)的基礎上再進行一次迭代就可以完成鍊錶的逆序,因此迴圈迭代的終止條件就是當前的head指標是null。

現在來總結一下,迴圈的初始條件是:

prev = null;

迴圈迭代體是:

next = head->next;

head->next = prev;

prev = head;

head = next;

迴圈終止條件是:

head == null

根據以上分析結果,逆序單鏈表的迴圈演算法如下所示:

61 link_node *reverselink(link_node *head)

6273

74return prev;75}

現在,我們用遞迴的思想來分析這個問題。先假設有這樣乙個函式,可以將以head為頭節點的單鏈表逆序,並返回新的頭節點指標,應該是這個樣子:

77 link_node *reverselink2(link_node *head)

現在利用reverselink2()對問題進行求解,將鍊錶分為當前表頭節點和其餘節點,遞迴的思想就是,先將當前的表頭節點從鍊錶中拆出來,然後對剩餘的節點進行逆序,最後將當前的表頭節點連線到新鍊錶的尾部。第一次遞迴呼叫reverselink2(head->next)函式時的狀態如圖(5)所示:

圖(5)第一次遞迴狀態圖

這裡邊的關鍵點是頭節點head的下乙個節點head->next將是逆序後的新鍊錶的尾節點,也就是說,被摘除的頭接點head需要被連線到head->next才能完成整個鍊錶的逆序,遞迴演算法的核心就是一下幾行**:

84     newhead = reverselink2(head->next);

/*遞迴部分*/

85     head->next->next = head;

/*回朔部分*/

86     head->next = null;

現在順著這個思路再進行一次遞迴,就得到第二次遞迴的狀態圖:

圖(6)第二次遞迴狀態圖

再進行一次遞迴分析,就能清楚地看到遞迴終止條件了:

圖(7)第三次遞迴狀態圖

遞迴終止條件就是鍊錶只剩乙個節點時直接返回這個節點的指標。可以看出這個演算法的核心其實是在回朔部分,遞迴的目的是遍歷到鍊錶的尾節點,然後通過逐級回朔將節點的next指標翻轉過來。遞迴演算法的完整**如下:

77 link_node *reverselink2(link_node *head)

78迴圈還是遞迴?這是個問題。當面對乙個問題的時候,不能一概認為哪種演算法好,哪種不好,而是要根據問題的型別和規模作出選擇。對於線性資料結構,比較適合用迭代迴圈方法,而對於樹狀資料結構,比如二叉樹,遞迴方法則非常簡潔優雅。

資料結構和演算法之單鏈表練習

三道大廠面試題 org.projectlombok groupid lombok artifactid 1.18 16 version dependency data noargsconstructor class heronode public string tostring 鍊錶操作 class...

資料結構和演算法 單鏈表

linkedlistlist new linkedlist list.add fan list.add 宋江 list.add 盧俊義 list.add 林沖 list.add 武松 list.insert 李逵 3 list.print public class linkednode public...

資料結構專題 線性表之單鏈表

對比了好幾本書,比較少涉及單鏈表的賦值,為了親自跑出其他功能,花了不少時間,畢竟是打基礎嘛,相信以後會越來熟練 你為什麼那麼熟練,明明是我先 話不多說,下面是 及實驗結果。include include define elementtype int define maxsize 1000 defin...