資料結構 單鏈表逆序

2021-08-08 07:38:03 字數 2604 閱讀 9798

2、 單鏈表逆序

第二個題目是很經典的「單鏈表逆序」問題。很多公司的面試題庫中都有這道題,有的公司明確題目要求不能使用額外的節點儲存空間,有的沒有明確說明,但是如果面試者使用了額外的節點儲存空間做中轉,會得到乙個比較低的分數。如何在不使用額外儲存節點的情況下使乙個單鏈表的所有節點逆序?我們先用迭代迴圈的思想來分析這個問題,鍊錶的初始狀態如圖(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迴圈還是遞迴?這是個問題。當面對乙個問題的時候,不能一概認為哪種演算法好,哪種不好,而是要根據問題的型別和規模作出選擇。對於線性資料結構,比較適合用迭代迴圈方法,而對於樹狀資料結構,比如二叉樹,遞迴方法則非常簡潔優雅。

資料結構 單鏈表逆序

2 單鏈表逆序 第二個題目是很經典的 單鏈表逆序 問題。很多公司的面試題庫中都有這道題,有的公司明確題目要求不能使用額外的節點儲存空間,有的沒有明確說明,但是如果面試者使用了額外的節點儲存空間做中轉,會得到乙個比較低的分數。如何在不使用額外儲存節點的情況下使乙個單鏈表的所有節點逆序?我們先用迭代迴圈...

資料結構單鏈表

初學資料結構,貼段自己編寫的單鏈表程式,希望自己能夠一直以強大的學習熱情持續下去!自勉!2012年3月30日 於大連 include using namespace std typedef struct node linklist,node linklist makelist int n void ...

資料結構 單鏈表

今天浪費了好多時間,也許是心裡想著明天的考試吧 可自己也知道這次的考試,自己畢竟過不了了,只好等到今年11月份,想想那時自己已經大三了 還有那麼多時間嗎!很懊惱今天不知怎麼回事,感嘆環境真的可以影響乙個人,真的可以 把今天的學習筆記寫下來,沒有進行好好的整理,這回單鏈表的功能較多,操作比較散,最後乙...