前言
嘮叨一下:半夜實在睡不着,起牀敲了一個 快速排序 的代碼,講真這是大學第一次親手敲出這個代碼,代碼使用Java實現,但算法和數據結構一樣,其本身和編程語言是沒有關係的。
簡單介紹
算法思想
基於分治的思想,是 冒泡排序 的改進型。
1.首先在數組中選擇一個基準點
(該基準點的選取可能影響快速排序的效率,後面講解選取的方法);
2.然後分別從數組的兩端掃描數組,設兩個指示標誌
(low 指向起始位置,high 指向末尾);
3.首先從後半部分開始,如果發現有元素比該基準點的值小,就交換low和high位置的值,然後從前半部分開始搜索,發現有元素大於基準點的值,就交換low和high位置的值,如此往復循環,直到 low>=high,然後把基準點的值放到high這個位置。
一次排序就完成了。
以後採用遞歸的方式分別對前半部分和後半部分排序,當前半部分和後半部分均有序時該數組就自然有序了。
算法特點
快速排序的時間主要耗費在劃分操作上,對長度爲k的區間進行劃分,共需k-1次關鍵字的比較;
最壞情況
每次劃分選取的基準都是當前無序區中關鍵字最小(或最大)的記錄,劃分的結果是基準左邊的子區間爲空(或右邊的子區間爲空),而劃分所得的另一個非空的子區間中記錄數目,僅僅比劃分前的無序區中記錄個數減少一個。時間複雜度爲O(n2);
最好情況
每次劃分所取的基準都是當前無序區的"中值"記錄,劃分的結果是基準的左、右兩個無序子區間的長度大致相等。總的關鍵字比較次數:O(nlogn);
儘管快速排序的最壞時間爲O(n2),但就平均性能而言,它是基於關鍵字比較的內部排序算法中速度最快者,快速排序亦因此而得名。它的平均時間複雜度爲O(nlogn)。
源碼
package nono.sort;
import java.util.Arrays;
/**
* 快速排序
*
* @author Nonoas
*/
public class QuikSorter {
/**
* 快速排序
*
* @param arry 進行排序的數組
* @param low 數組的起始下標
* @param high 數組的終止下標
*/
public static void quikSort(int[] arry, int low, int high) {
if (low >= high)
return; // 遞歸出口,當起始下標大於等於終止下標時,結束排序
int temp = arry[low]; // 臨時變量用於保存參考元素的值
int left = low; // 左端指針
int rigth = high; // 右端指針
while (left < rigth) {// 當左標小於右標時執行循環
while (left < rigth && arry[rigth] > temp)
rigth--; // 從後往前搜索小於中間值的數
if (left < rigth)
arry[left++] = arry[rigth]; // 將小於中間值的數移到左邊,這裏不用交換值,直接覆蓋即可
while (left < rigth && arry[left] < temp)
left++; // 從前往後搜索大於中間值的數
if (left < rigth)
arry[rigth--] = arry[left]; // 將大於中間值的數移到右邊,這裏不用交換值,直接覆蓋即可
}
// 循環體結束,說明左標與右標相遇
arry[left] = temp;// 將參考值賦給當前位置的數,此時左邊的數都小於temp,右邊的數都大於temp
quikSort(arry, low, left - 1);// 遞歸排序左部
quikSort(arry, rigth + 1, high);// 遞歸排序右部
}
public static void main(String[] args) {
int[] a = { 8, 7, 6, 3, 5, 4 };
System.out.println("排序前:" + Arrays.toString(a));
QuikSorter.quikSort(a, 0, a.length - 1);
System.out.println("排序後:" + Arrays.toString(a));
}
}