java簡單快速排序?qū)嵗馕?/h1>
更新時間:2017年08月11日 09:09:59 作者:五歲i
這篇文章主要為大家詳細(xì)介紹了java簡單快速排序?qū)嵗?,具有一定的參考價值,感興趣的小伙伴們可以參考一下
一、基本概念
找出一個元素(理論上可以隨便找一個)作為基準(zhǔn)(pivot),然后對數(shù)組進(jìn)行分區(qū)操作,使基準(zhǔn)左邊元素的值都不大于基準(zhǔn)值,基準(zhǔn)右邊的元素值 都不小于基準(zhǔn)值,如此作為基準(zhǔn)的元素調(diào)整到排序后的正確位置。遞歸快速排序,將其他n-1個元素也調(diào)整到排序后的正確位置。最后每個元素都是在排序后的正 確位置,排序完成。所以快速排序算法的核心算法是分區(qū)操作,即如何調(diào)整基準(zhǔn)的位置以及調(diào)整返回基準(zhǔn)的最終位置以便分治遞歸。
二、選擇基準(zhǔn)元
1、固定基準(zhǔn)元
如果輸入序列是隨機(jī)的,處理時間是可以接受的。如果數(shù)組已經(jīng)有序時,此時的分割就是一個非常不好的分割。因為每次劃分只能使待排序序列減一,此時為最壞情況,快速排序淪為冒泡排序,時間復(fù)雜度為Θ(n^2)。而且,輸入的數(shù)據(jù)是有序或部分有序的情況是相當(dāng)常見的。因此,使用第一個元素作為基準(zhǔn)元是非常糟糕的,應(yīng)該立即放棄這種想法。
2、隨機(jī)基準(zhǔn)元
這是一種相對安全的策略。由于基準(zhǔn)元的位置是隨機(jī)的,那么產(chǎn)生的分割也不會總是會出現(xiàn)劣質(zhì)的分割。在整個數(shù)組數(shù)字全相等時,仍然是最壞情況,時間復(fù)雜度是O(n^2)。實際上,隨機(jī)化快速排序得到理論最壞情況的可能性僅為1/(2^n)。所以隨機(jī)化快速排序可以對于絕大多數(shù)輸入數(shù)據(jù)達(dá)到O(n×log(n))的期望時間復(fù)雜度。
3、三數(shù)取中
最佳的劃分是將待排序的序列分成等長的子序列,最佳的狀態(tài)我們可以使用序列的中間的值,也就是第N/2個數(shù)??墒?,這很難算出來,并且會明顯減慢快速排序的速度。這樣的中值的估計可以通過隨機(jī)選取三個元素并用它們的中值作為基準(zhǔn)元而得到。事實上,隨機(jī)性并沒有多大的幫助,因此一般的做法是使用左端、右端和中心位置上的三個元素的中值作為基準(zhǔn)元。
三、partition算法
partition算法是快速排序的核心,在學(xué)習(xí)快排之前,可以先學(xué)習(xí)一下這個算法。下面先貼代碼:
public int partition(int[] num,int left,int right){
if(num==null || num.length<=0 || left<0 || right>=num.length){
return 0;
}
int prio=num[left+(right-left)/2]; //獲取數(shù)組中間元素的下標(biāo)
while (left<=right){ //從兩端交替向中間掃描
while (num[left]<prio)
left++;
while (num[right]>prio)
right--;
if (left<=right){
swap(num,left,right); //最終將基準(zhǔn)數(shù)歸位
left++;
right--;
}
}
return left;
}
這個方法的思路是先找一個樞紐元(這個方法實現(xiàn)里面找的是第一個元素,具體其實大有文章不過這里先簡化描述),再從數(shù)組的兩邊(具體從哪里到哪里由傳進(jìn)來額參數(shù)決定)生成兩個指針left和right,每次發(fā)現(xiàn)左邊的元素大于樞紐元則i停下來,右邊的元素小于樞紐元j就停下來,并且交換這個兩個數(shù)的位置。直到兩個指針left,right相遇。再把樞紐元插入left的位置,也就是它應(yīng)該在的位置。
這么做最后的結(jié)果是讓數(shù)組的[left,right]部分呈現(xiàn)出2部分,樞紐元最終位置以左都是小于等于樞紐元的,以右都是大于等于樞紐元的。而樞紐元則被插入到了一個絕對正確的位置。
四、排序算法實現(xiàn)
package sort;
/**
* 快速排序
* 快速排序采用了分治策略。就是在一個數(shù)組中取一個基準(zhǔn)數(shù)字,把小的數(shù)放基準(zhǔn)的左邊,大的數(shù)放基準(zhǔn)的右邊。
* 基準(zhǔn)左邊和右邊分別是新的序列。在新的序列中再取一個基準(zhǔn)數(shù)字,小的放左邊,大的放右邊。
* 這個里面用到的遞歸。我們需要三個參數(shù),一個是數(shù)組,另外兩個是序列的邊界
* @author HJS
*/
public class QuickSort{
void sort(int num[],int left,int right){
if (left<right){
int index=partition(num,left,right); //算出樞軸值
sort(num,left,index-1); //對低子表遞歸排序
sort(num,index+1,right); //對高子表遞歸排序
}
}
/**
* 調(diào)用partition(num,left,right)時,對num[]做劃分,
* 并返回基準(zhǔn)記錄的位置
* @param num
* @param left
* @param right
* @return
*/
public int partition(int[] num,int left,int right){
if(num==null || num.length<=0 || left<0 || right>=num.length){
return 0;
}
int prio=num[left+(right-left)/2]; //獲取數(shù)組中間元素的下標(biāo)
while (left<=right){ //從兩端交替向中間掃描
while (num[left]<prio)
left++;
while (num[right]>prio)
right--;
if (left<=right){
swap(num,left,right); //最終將基準(zhǔn)數(shù)歸位
left++;
right--;
}
}
return left;
}
public void swap(int[] num,int left,int right){
int temp = num[left];
num[left] = num[right];
num[right] = temp;
}
public static void main(String args[]){
int[] num={7,3,5,1,2,8,9,2,6};
new QuickSort().sort(num,0,num.length-1);
for(int n:num) {
System.out.print(n+" ");
}
}
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
-
Java實現(xiàn)雙鏈表互相交換任意兩個節(jié)點的方法示例
這篇文章主要介紹了Java實現(xiàn)雙鏈表互相交換任意兩個節(jié)點的方法,簡單講述了雙鏈表的概念,并結(jié)合實例形式給出了java雙鏈表實現(xiàn)任意兩個節(jié)點交換的操作技巧,需要的朋友可以參考下 2017-11-11
-
springboot中EasyPoi實現(xiàn)自動新增序號的方法
本文主要介紹了EasyPoi實現(xiàn)自動新增序號,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下 2021-09-09
-
java中的Io(input與output)操作總結(jié)(一)
所謂IO,也就是Input與Output的縮寫。在java中,IO涉及的范圍比較大,這里主要討論針對文件內(nèi)容的讀寫,感興趣的朋友可以了解下 2013-01-01
-
Java如何實現(xiàn)N叉樹數(shù)據(jù)結(jié)構(gòu)
這篇文章主要介紹了Java如何實現(xiàn)N叉樹數(shù)據(jù)結(jié)構(gòu)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教 2024-05-05
-
實戰(zhàn)分布式醫(yī)療掛號系統(tǒng)登錄接口整合阿里云短信詳情
這篇文章主要為大家介紹了實戰(zhàn)分布式醫(yī)療掛號系統(tǒng)登錄接口整合阿里云短信詳情,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪<BR> 2022-04-04
-
Java?ClassLoader虛擬類實現(xiàn)代碼熱替換的示例代碼
本文主要介紹了Java?ClassLoader虛擬類實現(xiàn)代碼熱替換的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧 2022-06-06
-
老生常談Java虛擬機(jī)垃圾回收機(jī)制(必看篇)
下面小編就為大家?guī)硪黄仙U凧ava虛擬機(jī)垃圾回收機(jī)制(必看篇)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧 2017-08-08
最新評論
一、基本概念
找出一個元素(理論上可以隨便找一個)作為基準(zhǔn)(pivot),然后對數(shù)組進(jìn)行分區(qū)操作,使基準(zhǔn)左邊元素的值都不大于基準(zhǔn)值,基準(zhǔn)右邊的元素值 都不小于基準(zhǔn)值,如此作為基準(zhǔn)的元素調(diào)整到排序后的正確位置。遞歸快速排序,將其他n-1個元素也調(diào)整到排序后的正確位置。最后每個元素都是在排序后的正 確位置,排序完成。所以快速排序算法的核心算法是分區(qū)操作,即如何調(diào)整基準(zhǔn)的位置以及調(diào)整返回基準(zhǔn)的最終位置以便分治遞歸。
二、選擇基準(zhǔn)元
1、固定基準(zhǔn)元
如果輸入序列是隨機(jī)的,處理時間是可以接受的。如果數(shù)組已經(jīng)有序時,此時的分割就是一個非常不好的分割。因為每次劃分只能使待排序序列減一,此時為最壞情況,快速排序淪為冒泡排序,時間復(fù)雜度為Θ(n^2)。而且,輸入的數(shù)據(jù)是有序或部分有序的情況是相當(dāng)常見的。因此,使用第一個元素作為基準(zhǔn)元是非常糟糕的,應(yīng)該立即放棄這種想法。
2、隨機(jī)基準(zhǔn)元
這是一種相對安全的策略。由于基準(zhǔn)元的位置是隨機(jī)的,那么產(chǎn)生的分割也不會總是會出現(xiàn)劣質(zhì)的分割。在整個數(shù)組數(shù)字全相等時,仍然是最壞情況,時間復(fù)雜度是O(n^2)。實際上,隨機(jī)化快速排序得到理論最壞情況的可能性僅為1/(2^n)。所以隨機(jī)化快速排序可以對于絕大多數(shù)輸入數(shù)據(jù)達(dá)到O(n×log(n))的期望時間復(fù)雜度。
3、三數(shù)取中
最佳的劃分是將待排序的序列分成等長的子序列,最佳的狀態(tài)我們可以使用序列的中間的值,也就是第N/2個數(shù)??墒?,這很難算出來,并且會明顯減慢快速排序的速度。這樣的中值的估計可以通過隨機(jī)選取三個元素并用它們的中值作為基準(zhǔn)元而得到。事實上,隨機(jī)性并沒有多大的幫助,因此一般的做法是使用左端、右端和中心位置上的三個元素的中值作為基準(zhǔn)元。
三、partition算法
partition算法是快速排序的核心,在學(xué)習(xí)快排之前,可以先學(xué)習(xí)一下這個算法。下面先貼代碼:
public int partition(int[] num,int left,int right){ if(num==null || num.length<=0 || left<0 || right>=num.length){ return 0; } int prio=num[left+(right-left)/2]; //獲取數(shù)組中間元素的下標(biāo) while (left<=right){ //從兩端交替向中間掃描 while (num[left]<prio) left++; while (num[right]>prio) right--; if (left<=right){ swap(num,left,right); //最終將基準(zhǔn)數(shù)歸位 left++; right--; } } return left; }
這個方法的思路是先找一個樞紐元(這個方法實現(xiàn)里面找的是第一個元素,具體其實大有文章不過這里先簡化描述),再從數(shù)組的兩邊(具體從哪里到哪里由傳進(jìn)來額參數(shù)決定)生成兩個指針left和right,每次發(fā)現(xiàn)左邊的元素大于樞紐元則i停下來,右邊的元素小于樞紐元j就停下來,并且交換這個兩個數(shù)的位置。直到兩個指針left,right相遇。再把樞紐元插入left的位置,也就是它應(yīng)該在的位置。
這么做最后的結(jié)果是讓數(shù)組的[left,right]部分呈現(xiàn)出2部分,樞紐元最終位置以左都是小于等于樞紐元的,以右都是大于等于樞紐元的。而樞紐元則被插入到了一個絕對正確的位置。
四、排序算法實現(xiàn)
package sort; /** * 快速排序 * 快速排序采用了分治策略。就是在一個數(shù)組中取一個基準(zhǔn)數(shù)字,把小的數(shù)放基準(zhǔn)的左邊,大的數(shù)放基準(zhǔn)的右邊。 * 基準(zhǔn)左邊和右邊分別是新的序列。在新的序列中再取一個基準(zhǔn)數(shù)字,小的放左邊,大的放右邊。 * 這個里面用到的遞歸。我們需要三個參數(shù),一個是數(shù)組,另外兩個是序列的邊界 * @author HJS */ public class QuickSort{ void sort(int num[],int left,int right){ if (left<right){ int index=partition(num,left,right); //算出樞軸值 sort(num,left,index-1); //對低子表遞歸排序 sort(num,index+1,right); //對高子表遞歸排序 } } /** * 調(diào)用partition(num,left,right)時,對num[]做劃分, * 并返回基準(zhǔn)記錄的位置 * @param num * @param left * @param right * @return */ public int partition(int[] num,int left,int right){ if(num==null || num.length<=0 || left<0 || right>=num.length){ return 0; } int prio=num[left+(right-left)/2]; //獲取數(shù)組中間元素的下標(biāo) while (left<=right){ //從兩端交替向中間掃描 while (num[left]<prio) left++; while (num[right]>prio) right--; if (left<=right){ swap(num,left,right); //最終將基準(zhǔn)數(shù)歸位 left++; right--; } } return left; } public void swap(int[] num,int left,int right){ int temp = num[left]; num[left] = num[right]; num[right] = temp; } public static void main(String args[]){ int[] num={7,3,5,1,2,8,9,2,6}; new QuickSort().sort(num,0,num.length-1); for(int n:num) { System.out.print(n+" "); } } }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Java實現(xiàn)雙鏈表互相交換任意兩個節(jié)點的方法示例
這篇文章主要介紹了Java實現(xiàn)雙鏈表互相交換任意兩個節(jié)點的方法,簡單講述了雙鏈表的概念,并結(jié)合實例形式給出了java雙鏈表實現(xiàn)任意兩個節(jié)點交換的操作技巧,需要的朋友可以參考下2017-11-11springboot中EasyPoi實現(xiàn)自動新增序號的方法
本文主要介紹了EasyPoi實現(xiàn)自動新增序號,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-09-09java中的Io(input與output)操作總結(jié)(一)
所謂IO,也就是Input與Output的縮寫。在java中,IO涉及的范圍比較大,這里主要討論針對文件內(nèi)容的讀寫,感興趣的朋友可以了解下2013-01-01Java如何實現(xiàn)N叉樹數(shù)據(jù)結(jié)構(gòu)
這篇文章主要介紹了Java如何實現(xiàn)N叉樹數(shù)據(jù)結(jié)構(gòu)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-05-05實戰(zhàn)分布式醫(yī)療掛號系統(tǒng)登錄接口整合阿里云短信詳情
這篇文章主要為大家介紹了實戰(zhàn)分布式醫(yī)療掛號系統(tǒng)登錄接口整合阿里云短信詳情,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪<BR>2022-04-04Java?ClassLoader虛擬類實現(xiàn)代碼熱替換的示例代碼
本文主要介紹了Java?ClassLoader虛擬類實現(xiàn)代碼熱替換的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06老生常談Java虛擬機(jī)垃圾回收機(jī)制(必看篇)
下面小編就為大家?guī)硪黄仙U凧ava虛擬機(jī)垃圾回收機(jī)制(必看篇)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-08-08