前言
唠叨一下:半夜實在睡不着,起床敲了一個 快速排序 的代碼,講真這是大學第一次親手敲出這個代碼,代碼使用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));
}
}