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)開(kāi)始,當(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ò)程演示:
求數(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),說(shuō)明在哨兵左側(cè),遞歸查找即可 return quickSortKMin(arr,begin,index-1,k); }else{ //如果k-1大于哨兵的下標(biāo),說(shuō)明在哨兵右側(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)開(kāi)始,當(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使用條件語(yǔ)句和循環(huán)結(jié)構(gòu)確定控制流(實(shí)例)
下面小編就為大家?guī)?lái)一篇Java使用條件語(yǔ)句和循環(huán)結(jié)構(gòu)確定控制流(實(shí)例)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧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í)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09基于SpringAI+DeepSeek實(shí)現(xiàn)流式對(duì)話功能
一般來(lái)說(shuō)大模型的響應(yīng)速度通常是很慢的,為了避免用戶用戶能夠耐心等待輸出的結(jié)果,我們通常會(huì)使用流式輸出一點(diǎn)點(diǎn)將結(jié)果輸出給用戶,那么問(wèn)題來(lái)了,想要實(shí)現(xiàn)流式結(jié)果輸出,后端和前端要如何配合?下來(lái)本文給出具體的實(shí)現(xiàn)代碼,需要的朋友可以參考下2025-02-02Java網(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-04IntelliJ IDEA 構(gòu)建maven多模塊工程項(xiàng)目(詳細(xì)多圖)
這篇文章主要介紹了IntelliJ IDEA 構(gòu)建maven多模塊工程項(xiàng)目(詳細(xì)多圖),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06