交換類排序的基本思想是經過交換逆序元素而最終達到全部元素有序,這裏的逆序是個廣義概念,若是按照降序排序,那麼前小後大的相鄰元素就爲逆序。常見的交換類排序方法有冒泡排序和快速排序。算法
冒泡排序法的思想比較簡單,依次掃描待排序的序列,而且從第一個元素開始比較相鄰兩個元素之間的大小,若是逆序則交換。假若有一個記錄序列 r[1,length],以升序爲例,在第i趟排序過程當中須要對前length-(i-1)個元素進行逆序交換,最終這些記錄中的最大元素將被交換到序列 中第length-(i-1)這個位置上。ui
1 |
void bubbleSort( int *r, int length) |
2 |
{ |
3 |
int n, change; |
4 |
int i, j, k; |
5 |
6 |
n = length; |
7 |
change = 1; |
8 |
9 |
for ( i = 1; i <= n - 1 && change; i++) { |
10 |
change = 0; |
11 |
for ( j = 1; j <= n - i; j++) |
12 |
if (r[j] > r[j + 1]) { |
13 |
r[0] = r[j]; |
14 |
r[j] = r[j + 1]; |
15 |
r[j + 1] = r[0]; |
16 |
change = 1; |
17 |
} |
18 |
output(r, length); |
19 |
} |
20 |
} |
對於n個元素的序列來講,整個冒泡排序最多進行n-1趟。這裏還特別的增長了一個標誌位change,只要作了逆序交換change就爲真,若是某一趟中沒有作任何交換,說明序列已經有序,則change爲假,此時整個排序能夠提早中止。code
冒泡算法中對相鄰元素的交換一次只能消除一個逆序,若是經過交換兩個不相鄰的元素能一次消除多個逆序,則會增長整個排序的速度。快速排序就是基於這樣的目的,在一次交換中能夠消除多個逆序。排序
快速排序的基本思想是在待排序記錄中選擇一個記錄做爲標準,將大於該標準的全部元素移到該標準以後,將小於該標準的全部元素移到該標準以前。最終將 待排序的記錄分紅兩個子序列,而標準元素插入到兩個子序列之間,上述過程爲一趟快速排序過程。接下來再對兩個子序列進行快速排序,不斷的分割子表,直到子 表長度不超過1爲止,此時全部的記錄都是有序的。遞歸
根據上述分析,能夠經過遞歸來實現快速排序法。quickPass()用於一趟快速排序,而且返回標準元素的位置pos。table
1 |
void quickSort( int *r, int low, int high, int length) |
2 |
{ |
3 |
int pos; |
4 |
5 |
6 |
if (low < high) { |
7 |
pos = quickPass(r, low, high); |
8 |
quickSort(r, low, pos - 1, length); |
9 |
quickSort(r, pos + 1, high, length); |
10 |
output(r, length); |
11 |
} |
12 |
} |
quickPass()用於實現一趟快速排序,一趟快速排序結束的條件是low不小於high。能夠看到快速排序中是將low和high兩個不相鄰位置的元素進行交換。class
1 |
int quickPass( int *r, int left, int right) |
2 |
{ |
3 |
int low, high; |
4 |
5 |
low = left; |
6 |
high = right; |
7 |
r[0] = r[low]; |
8 |
9 |
while (low < high) { |
10 |
while (low < high && r[high] >= r[0]) |
11 |
high--; |
12 |
if (low < high) { |
13 |
r[low] = r[high]; |
14 |
low++; |
15 |
} |
16 |
17 |
while (low < high && r[low] <= r[0]) |
18 |
low++; |
19 |
if (low < high) { |
20 |
r[high] = r[low]; |
21 |
high--; |
22 |
} |
23 |
} |
24 |
25 |
r[low] = r[0]; |
26 |
return low; |
27 |
} |
這裏也用到了r[0],用它來存儲標準元素,當一趟快速排序完成後,將標準元素插入low所指位置。方法