快速排序法一般來說可以分為三種,分別是:
①基礎快速排序法
②雙路快速排序法
③三路快速排序法
下面分別對以上三種快排進行梳理。
排序思路:首先傳入待排序陣列,使用變數l表示陣列下標起點,使用變數r表示陣列下標終點,然後取陣列第乙個元素e做中介,使用迴圈逐步將陣列元素分為比e小和不比e小的兩部分;使用變數j記錄左側比e小的元素個數下標(初始值為l),迴圈內部使用變數i從l+1開始遍歷到r,如果array[i]小於e,那麼array[j+1]與array[i]進行互換然後j++,否則直接i++;迴圈結束後,變數j位於比e小的那部分的最尾部下標處,將陣列待排序最左側元素與array[j]交換,最後得到l~j-1為比e小的部分,j+1~r為不比e小的部分。接著對l~j-1和j+1~r這兩部分繼續上述的排序操作,直到l>=r,排序結束。
**實現:
//基礎版快速排序法
public static void quicksortbase(int array)
public static void __quicksortbase(int array,int l,int r)
int e = array[l];
int j = l;//儲存生成20個0~66的數,進行測試:
此版本可以進行的優化:
①每次排序前,先將陣列最左邊的數和陣列中的元素隨機互換一下,然後再取陣列最左邊的元素e做中介。
作用:解決對幾乎整體有序的陣列進行排序時,會導致效率低下的問題。
public static void __quicksortbase(int array,int l,int r)
//優化1:先隨機取下標,然後與最左元素交換下
int index = (int) (math.random()*(r-l)+l);
temp = array[l];
array[l] = array[index];
array[index] = temp;
int e = array[l];
int j = l;//儲存②當待排序部分元素個數小的時候,進行優化版的插入排序,提高效率
public static void __quicksortbase(int array,int l,int r)
//優化2:使用優化版的插入排序改進效率
if(r-l<=15)
//優化1:先隨機取下標,然後與最左元素交換下
int index = (int) (math.random()*(r-l)+l);
temp = array[l];
array[l] = array[index];
array[index] = temp;
int e = array[l];
int j = l;//儲存排序思路:首先傳入待排序陣列,使用變數l表示陣列下標起點,使用變數r表示陣列下標終點,然後取陣列左側第乙個元素v做中介,宣告變數i初始值為l+1,宣告變數j初始值為r,如果i<=r&&array[i]比v小,i++,直到array[i]>=v;如果j>=l+1&&array[j]比v大,j--,直到array[j]<=v;交換array[i]和array[j],確保下標從l~i的陣列元素均小於等於v,下標從j~r的陣列元素均大於等於v,接著i++,j--;迴圈完成後,j的位置是陣列中<=v的最後乙個元素位置,將其與array[l]互換,接著繼續對l~j-1和j+1~r的兩部分進行雙路快排。
**實現:
//雙路快排,解決大量重複值的陣列排序
public static void quicksort2(int array)
public static void _quicksort2(int array,int l,int r)
//優化:先隨機取下標,然後與最左元素交換下
int index = (int) (math.random()*(r-l)+l);
int temp = array[l];
array[l] = array[index];
array[index] = temp;
int v = array[l];//最左側元素做中介
int i = l+1,j = r;
while(true)//如果array[j]大於v,j--;直到碰到不大於v的元素時停止
if(i>j)
//交換array[i]和array[j],保證下標從l~i的元素值均小於等於v,下標從j~r的元素值均大於等於v
temp = array[i];
array[i] = array[j];
array[j] = temp;
i++;
j--;
} //迴圈結束後,j位於<=v的最後乙個元素位置,交換array[j]和array[l];此時l~j均小於等於v,下標從j~r的元素值均大於等於v,array[j]==v
temp = array[l];
array[l] = array[j];
array[j] = temp;
_quicksort2(array,l,j-1);
_quicksort2(array,j+1,r);
}
排序思路:
首先傳入待排序陣列,使用變數l表示陣列下標起點,使用變數r表示陣列下標終點,然後取陣列左側第乙個元素v做中介,宣告變數i初始值為l+1,宣告變數lt初始值為l,宣告變數gt初始值為r+1,先將陣列分為三部分,array[l+1]~array[lt]的部分v,將其與gt-1交換,並且gt--,此時gt~r的部分大於v;如果array[i]==v,直接i++即可。迴圈終止時,lt位於array中**實現:
// 三路快排,將陣列分為v三部分處理
public static void quicksort3(int array)
public static void _quicksort3(int array, int l, int r)
// 優化:先隨機取下標,然後與最左元素交換下
int index = (int) (math.random() * (r - l) + l);
int temp = array[l];
array[l] = array[index];
array[index] = temp;
int v = array[l];// 最左側元素做中介
int i=l+1,lt=l,gt=r+1;//array[l+1...lt]v,array[lt+1....i]==v
while(iv)else
} //迴圈結束後,lt位於小於v的部分的最後乙個元素,將其與最左側交換
temp = array[l];
array[l] = array[lt];
array[lt] = temp;
//繼續對小於v和大於v的兩部分進行三路快排
_quicksort3(array, 0, lt-1);
_quicksort3(array, gt, r);
}
排序演算法 快速排序法
1 無論是冒泡法 堆排序法還是歸併法排序,都是重複找到陣列中剩餘未排序元素的最大或最小值,然後將每次找到的最大或最小值依次放進陣列中就可以得到乙個有序的陣列。快速排序法也與其類似,但不同的是,快速排序是通過任意指定陣列中的乙個元素作為基準,比該元素大的放在右邊,比該元素小的放在左邊,這樣就可以保證指...
C 排序演算法 快速排序法
在閱讀此博文前,請先閱讀我的博文 排序演算法 基類設計 以了解基類的結構。在編寫 前,我們先來了解二路歸併法的排序過程 假設有乙個ilist型的集合list 集合的元素為list 0 到list n 1 n list.count 第1步 從a 0 n 1 中選擇乙個元素作為middle,該元素為支點...
排序演算法 快速排序(分治法)
思想 快速排序採用的思想是分治思想。快速排序是找出乙個元素 理論上可以隨便找乙個 作為基準 pivot 然後對陣列進行分割槽操作,使基準左邊元素的值都不大於基準值,基準右邊的元素值 都不小於基準值,如此作為基準的元素調整到排序後的正確位置。遞迴快速排序,將其他n 1個元素也調整到排序後的正確位置。最...