參考書籍:數據結構(C語言版)嚴蔚敏吳偉民編著清華大學出版社
本文中的代碼可從這裏下載:https://github.com/qingyujean/data-structure
1.冒泡排序
1.1基本思想
小的浮起,大的沉底
具體做法:
第一趟:第1個與第2個比較,大則交換;第2個與第3 比較,大則交換,… 關鍵字最大的記錄交換到最後一個位置上;
第二趟:對前n-1個記錄進行同樣的操作,關鍵字次大 的記錄交換到第n-1個位置上;依次類推,則完成排序。
1.2代碼實現
package sort.swampSort;
public class BubbleSort {
/**
* @param args
*/
//冒泡排序
public static void bubbleSort(int[] L){
for(int i = L.length-1; i > 1; i--){//i控制比較的趟數,比較n-1趟
for(int j = 1; j < i; j++){
if(L[j] > L[j+1]){//交換
L[0] = L[j+1];
L[j+1] = L[j];
L[j] = L[0];
}
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] test = {0, 25, 56, 49, 78, 11, 65, 41, 36}; //0號單元未使用
bubbleSort(test);
for(int i = 1; i <= test.length-1; i++)
System.out.print(test[i]+" ");
}
}
運行結果:
1.3性能分析
正序:只需進行一趟排序,在排序過程中進行n-1次關鍵字間的比較,且不移動記錄;時間複雜度爲O(n) 。
逆序:需要進行n-1趟排序,需要進行n(n-1)/2次比較,並作等數量級的記錄移動。總的時間複雜度爲O(n^2) 。
起泡排序方法是穩定的。適合於數據較少的情況。
2.快速排序
2.1基本思想
背景:起泡排序的過程可見,起泡排序是一個增加有序序列長度的過程,也是一個縮小無序序列長度的過程,每經過一趟起泡,無序序列的長度只縮小 1。試設想:若能在經過一趟排序,使無序序列的長度縮小一半,則必能加快排序的速度。
基本思想:通過一趟排序將待排序列以樞軸爲標準劃分成兩部分,使其中一部分記錄的關鍵字均比另一部分小,再分別對這兩部分進行快速排序,以達到整個序列有序。通常取第一個記錄的值爲基準值或樞軸。
具體做法:附設兩個指針low和high,初值分別指向第一個記錄和最後一個記錄,設樞軸爲 key;
(1)從high 所指位置起向前搜索,找到第一個不大於基準值的記錄與樞軸記錄相互交換;
(2)從low 所指位置起向後搜索,找到第一個不小於基準值的記錄與樞軸記錄相互交換。
(3)重複這兩步直至low=high爲止。
2.2代碼實現
package sort.swampSort;
public class QuickSort {
/**
* @param args
*/
//交換順序表L的字表L[low...high]的記錄,樞軸記錄到爲,並返回樞軸應該所在的位置
//此時,樞軸前面的記錄均小於樞軸,樞軸後面的記錄均大於樞軸
//是一趟快排
public static int partion(int[] L, int low, int high){
L[0] = L[low];//L[0]暫存樞軸,字表中的第一個元素一般默認爲是樞軸
while(low < high){
while(low < high && L[0] <= L[high])
high--;
//此時L[high]>L[0]
L[low++] = L[high];
while(low < high && L[0] >= L[low])
low++;
//此時L[low]>L[0]
L[high--] = L[low];
}
//循環結束時,一定有low==high
L[low] = L[0];
return low;
}
//遞歸形似的快速排序
public static void quickSort(int[] L, int low, int high){
//對順序表L的子序列L[low...high]做快速排序
if(low < high){
int m = partion(L, low, high);
quickSort(L, low, m-1);
quickSort(L, m+1, high);
}
//low==high時,說明子序列中僅有一個元素了,顯然已經有序,應作爲每一層遞歸的結束
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] test = {0, 46, 55, 13, 42, 94, 5, 17, 70}; //0號單元未使用
quickSort(test, 1, test.length-1);
for(int i = 1; i <= test.length-1; i++)
System.out.print(test[i]+" ");
}
}
運行結果:
2.3性能分析
最好的情形(左、右子區間的長度大致相等),快速排序的最好時間複雜度應爲O(nlog2n)。
最壞的情形(每次能劃分成兩個子區間,但其中一個是空),快速排序的最壞時間複雜度爲O(n^2),退化成冒泡排序。
對n較大的情況,它是平均速度最快的排序算法,但當n很小時,此方法往往比其他簡單排序方法還要慢。
快速排序是不穩定的。