Transcript 下載/瀏覽
快速排序法 (Quick Sort)
• 從待排序的資料中取出一筆資料 ( 通常是第一筆 )
當作基準值 (Pivot Key),將基準鍵值逐一與其他
所有資料作比較後,可以直接將基準鍵值之資料
放置於正確位置,且把其他所有的資料分割成兩
組子集合:
– 小於此鍵值的集合
– 大於此鍵值的集合。
• 接著便可以再對這兩個子集合分別作快速排序,
也就是再從其中分別選出基準鍵值繼續作快速排
序。
• 利用分而治之 (divide and conquer)的精神
快速排序法的運作步驟
假設有n 筆資料要排序,運作步驟如下:
1. 從未排序資料中取出第一筆資料當作基準鍵值p (Pivot
Key)。
2. 由前向後找到第一個比 p 大的資料,設此資料的位置為
i。
3. 由後向前找到第一個比 p 小的資料,設此資料的位置為
j。
4. 若 i < j ,則將i, j 位置的資料互相交換。
5. 重複步驟2, 3, 4,直到 i > j 為止。
6. 將p 與目前位置j 的資料交換 。(則p 已放置於正確位置,
且把其他所有的資料分割成兩組子集合,小於p 的資料皆
於資料p 的前面,大於p 的資料皆於資料p 的後面。)
7. 對這兩個子集合分別重複步驟1~6,直到每個子集合均只
範例
排序的資料為 23 44 13 30 37 19 10
26,則第一階段的快速排序過程如下:
快速排序法過程
說
明
[0] [1] [2] [3] [4] [5]
[6]
[7]
初值
23 44 13 30 37 19
10
26 設定基準為23
pass
1
23 44 13 30 37 19
i
10
j
26 因44 > 23,i = 1
因10 < 23,j = 6
因 i < j,將44與10交
換
23 10 13 30 37 19
i
j
44
26 因30 > 23,i = 3
因19 < 23,j = 5
因 i < j,將30與19交
換
23 10 13 19 37 30
j i
44
26 因37 > 23,i = 4
因19 < 23,j = 3
因 i > j,將23與19交
換
例﹕ 資料之鍵值為15, 18, 33, 10, 27, 11, 13, 42,
20,請以快速排序法排序,假設以第一筆當作基準
鍵值,請寫出排序的過程及其結果。
解:
鍵
值
步驟
[0]
[1]
[2]
[3]
[4]
[5]
[6]
[7]
[8]
pass 1:
[10
13
11]
15
[27
33
18
42
20]
pass 2:
10
[13
11]
15
[27
33
18
42
20]
pass 3:
10
[11]
13
15
[27
33
18
42
20]
pass 4:
10
11
13
15
[18
20]
27
[42
33]
pass 5:
10
11
13
15
18
[20]
27
[42
33]
pass 6:
10
11
13
15
18
20
27
[33]
42
結 果:
10
11
13
15
18
20
27
33
42
快速排序法的函數quick_sort( )
• 假設有n筆整數資料儲存於整數陣列a中:
/*快速排序法:使用遞迴的觀念*/
void quick_sort (int a[], int left, int right)
{
int key, i, j, temp;
if( left < right ) { /*當兩筆資料以上才要排序*/
key = a[left]; /*以第一筆當作基準值*/
i = left;
/*左端位置*/
j = right;
/*右端位置*/
while( i<j ) {
/*由前向後找第一筆比基準值大的值*/
while ( i < right && a[i] <= key ) i++;
/*由後向前找第一筆比基準值小的值*/
while( j > left && a[j] >= key ) j--;
if( i < j ) {
/*若與排序規則不符,將資料交換*/
temp = a[i];
a[i] = a[j];
a[j] = temp;
} /*if*/
} /*while*/
temp = a[left]; /*將基準值之資料與目前位置j的資料交換*/
a[left] = a[j];
a[j] = temp;
/*使用遞迴,對兩個子集合分別作排序*/
quick_sort( a, left, j-1 );
quick_sort( a, j+1, right );
}
} /*quick_sort()*/