單鏈表的快速排序

2021-08-21 11:05:02 字數 2861 閱讀 6967

單鏈表的快速排序

首先,很容易想到的是:

要做一輪基準值定位,怎麼做?

要做左子鍊錶和右子鍊錶的遞迴,怎麼做?

第二個問題比較好回答,只要知道子鍊錶的首尾節點,就可以做遞迴了。偽**是:

void

quick_sort_link

(node *start, node *end=

null

);

第乙個問題才是要解決的難題。思路如下:

假設第一輪基準值定位做完了,我們需要有什麼才能繼續進行?

很顯然,需要有左子鍊錶和右子鍊錶的各自的首尾節點。那麼,左鍊錶的首節點和右鍊錶的尾節點,這2個一開始就有了。所以,需要有的是:左子鍊錶的尾節點,和 右子鍊錶的首節點。而這2個節點分別位於基準值節點的左邊和右邊。

這個時候,有乙個思路是:使用2個輔助指標 p1 和 p2.

p1 負責維護左子鍊錶,它是左子鍊錶的最後乙個節點;

p2 負責維護右子鍊錶,它不斷右移:其實,相當於p2在不斷擴充右子鍊錶,而待探索區不斷縮小

當p2在探索區發現大值的時候,只需右移即可,將其納入右子鍊錶的範圍;

當p2發現小值的時候,就要把p1右移乙個(相當於擴大左子鍊錶的範圍),然後交換p1和p2的值(把小值和原來右子鍊錶的最後乙個節點交換),然後p2繼續右移。

到最後,還需要交換基準值和p1的值,因為,基準值從來沒有動過,還在第乙個節點的位置,而p1最終已經指向左子鍊錶的最後乙個位置,因此需要交換它們2個。

所以,**就是

int t = start-

>data;

// 基準值

while

(p2 != end)

p2 = p2-

>next;

}swap

(start-

>data, p1-

>data)

;

問題是:按上面的演算法,初始狀態也是正確的嗎?

這個時候可以舉幾個例子來驗證了!(這是白板程式設計時的重要方法!)

比如:15 -> 1 -> 20, *p1=15, *p2=1,

15 -> 1 -> 20, *p1=1, *p2=20,

15 -> 1 -> 20, *p1=1, *p2=null

此時,需交換start和p1的值,即:

1-> 15 -> 20

驗證成功!

又比如:

10 -> 2 -> 50 -> 3 -> 20, *p1=10, *p2=2, t=10

*p1=2, *p2=2, 10 -> 2 -> 50 -> 3 -> 20,

*p1=2, *p2=50, 10 -> 2 -> 50 -> 3 -> 20,

*p1=2, *p2=3, 10 -> 2 -> 50 -> 3 -> 20,

*p1=50, *p2=3, 10 -> 2 -> 50 -> 3 -> 20,

*p1=3, *p2=20, 10 -> 2 -> 3 -> 50 -> 20,

*p1=3, *p2=null, 10 -> 2 -> 3 -> 50 -> 20,

此時交換p1和start的值

3 -> 2 -> 10 -> 50 -> 20

驗證成功!

再重複一遍,以上乙個要點是,在最後需要交換p1和start的值。

原因是,迴圈結束的時候,p1的值是左子鍊錶的最後乙個節點,它的後面就是右子鍊錶了; 而start的值就是基準值,它一直在第1個節點的位置沒有動過;所以需要交換。

完整的**是:

#include

using

namespace std;

// int array = ; // 12, 13, 14, 23, 34, 45, 54, 89, 99, 100

int array=

;struct node };

void

print_list

(node* head)

if(head && head-

>next ==

null)}

node*

create_list

(int

* array,

int size)

return head;}/*

基準值是start->data;

將原鍊錶看作2個鍊錶:左煉表和右鍊錶,左鍊錶最後乙個節點就是基準值

p1是左鍊錶的最後乙個節點,p2是右鍊錶的最後乙個節點

因此,當遇到大於基準值的時候,p2一直右移;

當遇到小於基準值的時候,p1右移乙個,再交換p1和p2的值,相當於維持了p1和p2的定義

一輪迴圈的最後,p2到達了end的位置,此時,應該交換p1和start節點的值,這時才是真正的一輪處理的結束

下一輪,就遞迴呼叫 qs(start, p1) 和 qs(p1->next, end) 了。

*/void

quick_sort_list

(node* start, node* end=

null

) p2 = p2-

>next;

}swap

(p1-

>data, start-

>data)

;quick_sort_list

(start, p1)

;quick_sort_list

(p1-

>next, end);}

intmain()

(完)

單鏈表快速排序

今天在學習 程式設計師使用演算法 時,看到了單鏈表快排序這一節。初看時感覺程式有很大的問題,但是細細品味之後卻發現程式設計的極為巧妙,同時又深感自己c語言指標知識之不牢固,特別是指標的指標方面的知識。單鏈表的快排序和陣列的快排序基本思想相同,同樣是基於劃分,但是又有很大的不同 單鏈表不支援基於下標的...

單鏈表快速排序

今天在學習 程式設計師使用演算法 時,看到了單鏈表快排序這一節。初看時感覺程式有很大的問題,但是細細品味之後卻發現程式設計的極為巧妙,同時又深感自己c語言指標知識之不牢固,特別是指標的指標方面的知識。單鏈表的快排序和陣列的快排序基本思想相同,同樣是基於劃分,但是又有很大的不同 單鏈表不支援基於下標的...

單鏈表快速排序

今天在學習 程式設計師使用演算法 時,看到了單鏈表快排序這一節。初看時感覺程式有很大的問題,但是細細品味之後卻發現程式設計的極為巧妙,同時又深感自己c語言指標知識之不牢固,特別是指標的指標方面的知識。單鏈表的快排序和陣列的快排序基本思想相同,同樣是基於劃分,但是又有很大的不同 單鏈表不支援基於下標的...