Java快速排序及求數(shù)組中第k小的值解析
快速排序
假設(shè)有一個(gè)如下數(shù)組,對(duì)其進(jìn)行快速排序
[2,90,4,67,234,1,87]
思路:選一個(gè)中間值,把數(shù)組中比它小的元素放到左邊,比它大的元素放到右邊,這時(shí)形成三個(gè)子數(shù)組,分別是中間值,比它大的數(shù)和比它小的數(shù),然后對(duì)前后兩個(gè)數(shù)組進(jìn)行遞歸
最好時(shí)間復(fù)雜度:O(NlogN)
最差時(shí)間復(fù)雜度:O(N^2)
代碼實(shí)現(xiàn)(java)
采用哨兵的概念,設(shè)數(shù)組最后一個(gè)元素為哨兵
public static void quickSort(int[] arr,int begin,int end){
//遞歸必須滿足條件:起始值小于終止值
if(begin<end){
//這個(gè)方法是確定數(shù)組哨兵在排序后的最終位置下標(biāo),由于哨兵左邊的數(shù)都小于哨兵,右邊的數(shù)都大于哨兵,所以對(duì)兩邊子數(shù)組進(jìn)行遞歸
int index = partition(arr,begin,end);
//對(duì)左邊的子數(shù)組進(jìn)行遞歸
quickSort(arr,begin,index-1);
//對(duì)右邊的數(shù)組進(jìn)行遞歸
quickSort(arr,index+1,end);
}
}
public static int partition(int[] arr,int begin,int end){
//將數(shù)組的最后一個(gè)元素作為哨兵
int pivot = arr[end];
//i為起始坐標(biāo)-1
int i = begin -1;
//對(duì)數(shù)組進(jìn)行遍歷,j從數(shù)組的第一個(gè)下標(biāo)開始,當(dāng)j對(duì)應(yīng)元素小于哨兵時(shí),i加1,交換i和j對(duì)應(yīng)元素
for (int j = begin; j < end; j++) {
//當(dāng)
if(arr[j]<=pivot){
i++;
int tmp = arr[i];
arr[i]=arr[j];
arr[j]=tmp;
}
}
//遍歷結(jié)束后,交換arr[i+1]和哨兵的值
int tmp = arr[i+1];
arr[i+1]=arr[end];
arr[end]= tmp;
//i+1就是哨兵最終排序后對(duì)應(yīng)的下標(biāo)
return i+1;
}
過程演示:

求數(shù)組中第k小的值
分析:第k小的值,就是下標(biāo)為k-1的值
代碼實(shí)現(xiàn)(java)
public static int quickSortKMin(int[] arr,int begin,int end,int k){
//遞歸必須滿足條件:起始值小于等于終止值
if(begin<=end){
//這個(gè)方法是確定數(shù)組哨兵在排序后的最終位置下標(biāo),由于哨兵左邊的數(shù)都小于哨兵,右邊的數(shù)都大于哨兵,所以對(duì)兩邊子數(shù)組進(jìn)行遞歸
int index = partition(arr,begin,end);
//如果哨兵的下標(biāo)就等于k-1,那哨兵就是數(shù)組中第k小的值,直接輸出
if(index==k-1){
return arr[index];
}else if(index > k-1){
//如果k-1小于哨兵的下標(biāo),說明在哨兵左側(cè),遞歸查找即可
return quickSortKMin(arr,begin,index-1,k);
}else{
//如果k-1大于哨兵的下標(biāo),說明在哨兵右側(cè),遞歸查找即可
return quickSortKMin(arr,index+1,end,k);
}
}
return Integer.MIN_VALUE;
}
public static int partition(int[] arr,int begin,int end){
//將數(shù)組的最后一個(gè)元素作為哨兵
int pivot = arr[end];
//i為起始坐標(biāo)-1
int i = begin -1;
//對(duì)數(shù)組進(jìn)行遍歷,j從數(shù)組的第一個(gè)下標(biāo)開始,當(dāng)j對(duì)應(yīng)元素小于哨兵時(shí),i加1,交換i和j對(duì)應(yīng)元素
for (int j = begin; j < end; j++) {
//當(dāng)
if(arr[j]<=pivot){
i++;
int tmp = arr[i];
arr[i]=arr[j];
arr[j]=tmp;
}
}
//遍歷結(jié)束后,交換arr[i+1]和哨兵的值
int tmp = arr[i+1];
arr[i+1]=arr[end];
arr[end]= tmp;
//i+1就是哨兵最終排序后對(duì)應(yīng)的下標(biāo)
return i+1;
}
到此這篇關(guān)于Java快速排序及求數(shù)組中第k小的值解析的文章就介紹到這了,更多相關(guān)Java快速排序及求數(shù)組值內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java使用條件語句和循環(huán)結(jié)構(gòu)確定控制流(實(shí)例)
下面小編就為大家?guī)硪黄狫ava使用條件語句和循環(huán)結(jié)構(gòu)確定控制流(實(shí)例)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-06-06
使用SpringSecurity 進(jìn)行自定義Token校驗(yàn)
這篇文章主要介紹了使用SpringSecurity 進(jìn)行自定義Token校驗(yàn)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06
基于java實(shí)現(xiàn)DFA算法代碼實(shí)例
這篇文章主要介紹了基于java實(shí)現(xiàn)DFA算法代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09
基于SpringAI+DeepSeek實(shí)現(xiàn)流式對(duì)話功能
一般來說大模型的響應(yīng)速度通常是很慢的,為了避免用戶用戶能夠耐心等待輸出的結(jié)果,我們通常會(huì)使用流式輸出一點(diǎn)點(diǎn)將結(jié)果輸出給用戶,那么問題來了,想要實(shí)現(xiàn)流式結(jié)果輸出,后端和前端要如何配合?下來本文給出具體的實(shí)現(xiàn)代碼,需要的朋友可以參考下2025-02-02
Java網(wǎng)絡(luò)編程之簡(jiǎn)單的服務(wù)端客戶端應(yīng)用實(shí)例
這篇文章主要介紹了Java網(wǎng)絡(luò)編程之簡(jiǎn)單的服務(wù)端客戶端應(yīng)用,以實(shí)例形式較為詳細(xì)的分析了java網(wǎng)絡(luò)編程的原理與服務(wù)器端客戶端的實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-04-04
IntelliJ IDEA 構(gòu)建maven多模塊工程項(xiàng)目(詳細(xì)多圖)
這篇文章主要介紹了IntelliJ IDEA 構(gòu)建maven多模塊工程項(xiàng)目(詳細(xì)多圖),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06

