最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java實現快速排序過程分析

 更新時間:2018年10月12日 11:56:55   作者:CGZ_PaPa  
今天小編就為大家分享一篇關于Java實現快速排序過程分析,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧

快速排序過程

沒有既不浪費空間又可以快一點的排序算法呢?那就是“快速排序”!光聽這個名字是不是就覺得很高端呢。

假設我們現在對“52 39 67 95 70 8 25 52'”這個8個數進行排序。首先在這個序列中隨便找一個數作為基準數(不要被這個名詞嚇到了,就是一個用來參照的數,待會你就知道它用來做啥的了)。為了方便,就讓第一個數70作為基準數吧。接下來,需要將這個序列中所有比基準數大的數放在70的右邊,比基準數小的數放在70的左邊,類似下面這種排列:

 8 25 39 52 52' 67 70 95

在初始狀態(tài)下,數字70在序列的第5位。我們的目標是將70挪到序列中間的某個位置,假設這個位置是k?,F在就需要尋找這個k,并且以第k位為分界點,左邊的數都小于等于70,右邊的數都大于等于70。想一想,你有辦法可以做到這點嗎?

基本思想是分治的思想,說到分治,就應該想到和遞歸是分不開的。

有些書上會使用關鍵字比較的表述,有些書上會直接使用記錄比較表述,這兩種說法是兩個維度上的說法。這里序列元素的關鍵字屬于記錄的一部分,為了簡化問題,本文的討論并不區(qū)分關鍵字和記錄,代碼實現中使用整數來表示記錄。簡而言之,本文的討論簡化為,對整型數組的快速排序。

通過一趟排序將要排序的記錄分割成兩部分,一部分的關鍵字值比別一部分的所有關鍵字都小,然后再依次對前后兩部分的記錄進行快速排序,遞歸該過程,直到序列中所有記錄都是有序為止。

步驟

1)分解。選擇第一個元素作為基準數,將輸入序列array[m…n]劃分成兩個非空序列array[m…k]和array[k+1…n],使array[m…k]中任一元素的值不大于array[k+1…n]任一元素值。

2)遞歸求解。通過遞歸調用快排算法分別對array[m…k]和array[k+1…n]進行排序

3)合并。由于對分解出的兩個子序列排序都是原地進行的,所以在array[m…k]和array[k+1…n]都排好序后不需要再執(zhí)行任何計算,就能將array[m…n]排好序。因此這一步是不需要在程序中體現的。

排序過程分析

初始關鍵字:52 39 67 95 70 8 25 52' ,下面將列出每一趟執(zhí)行的結果。

基準52: 52 39 67 95 70 8 25 52'

基準25: 8 25 39 52 70 95 67 52‘

基準70: 8 25 39 52 52' 67 70 95

基準52‘:8 25 39 52 52' 67 70 95

算法分析

快速排序的時間復雜度與關鍵字初始序列有關。

最壞時間復雜度:O(n^2):

以第一個數或最后一個數為基準時,當初始序列整體或局部有序時,快速排序的性能會下降。若整體有序,此時,每次劃分只能分出一個元素,具有最壞時間復雜度,快速排序將退化成冒泡排序。

最好時間復雜度:

每次選取的基準關鍵字都是待排序列的中間值,也就是說每次劃分可以將序列劃分為長度相等的兩個序列??焖倥判虻倪f歸過程可以用一棵二叉樹來表示,遞歸樹的高度是2為底的對數,每層需要比較的次數是n/2,所以最好時間復雜度是O(n*以2為底n的對數),因為很多時候輸入序列都是亂序的,所以最好時間復雜度也是平均時間復雜度。

三種快排和四種優(yōu)化方法

三種快排

這里區(qū)分的方式是不同基準的選擇方法:

1)固定位置,取第一個或最后一個元素作為基準。這種選取方法不合適局部有序的輸入。

2)隨機選取基準,利用隨機算法,選取待排序序列中任意一個元素作為基準。

3)三數取中,取數列中第一個數,中間位置的數,最后一個數作一個平均值作為基準。

四種優(yōu)化

1)當排序序列長度分割到一定程度時,使用插入排序

對于N很小或局部有序的數組,直接插入排序的效率非常高。

2)在一次分割結束后,可以把與基準數相等的元素聚在一起,下次分割時忽略掉這些元素。

對于含有重復元素比較多的序列,這種優(yōu)化方法效果比較好,可以減少很多跌代次數。

具本過程:

第一步:在劃分過程,把與所選取的基準數相等的元素放在數組的兩端。

第二步:劃分結束后,把兩端的與基準數相等的元素移到基準數最終位置的兩側。

3)優(yōu)化遞歸操作。

4)使用多線程并行處理子劃分。

Partition方法在求TopK問題上的應用

TopK問題即求序列中最大或最小的K個數。這里以求最小K個數為例。

快速排序的思想是使用一個基準元素將數組劃分成兩部分,左側都比基準數小,右側都比基準數大。

給定數組array[low…h(huán)igh],一趟快排劃分后的結果有三種:

1)如果基準數左側元素個數Q剛好是K-1,那么在基準數左側(包含基準數本身),即為TopK的所有元素。

2)如果基準數左側元素個數Q小于K-1,那么說明基準數左側的Q個數都是TopK里的元素,只需要在基準數的右側找出剩下的K-Q個元素即可。問題轉化成了以基準數下標為起點,高位(high)為終點的Top(K-Q)。遞歸下去即可。

3)如果基準數左側元素個數Q大于K-1,說明第K個位置,在基準數的左側,需要縮小搜索范圍,在低位(low)至基準數位置重復遞歸即可,最終問題會轉化成上面兩種情況。

快排java實現

在手寫快排算法時,最好先把一趟排序的過程寫出來。

package sort;
public class QuickSort {
 // 暴露只一個參數的公共接口
 public void quickSort(int a[]) {
 sort(a, 0, a.length - 1);
 }
 // 快排算法的真正實現
 private void sort(int[] a, int low, int high) {
 if (low >= high)
 return;
 int i = low, j = high; // 設置這兩個變量的目的是為了保持low和high不變
 int pivotNum = a[i]; // 基準數
 while (i < j) {
 while (a[j] >= pivotNum && j > i) { // 循環(huán)結束的條件有二:一是找到比支點小的數,二是j==i
 j--;
 }
 if (j > i) { // 由于上面循環(huán)結束的功能性有兩個,對于找到比支點小的數,即j!=i,要進行位置的交換,下同
 a[i] = a[j];
 i++;
 }
 while (a[i] < pivotNum && i < j) { 
 i++;
 }
 if (i < j) {
 a[j] = a[i];
 j--;
 }
 }
 a[i] = pivotNum;
 sort(a, low, i - 1);
 sort(a, i + 1, high);
 }
 public static void main(String[] args) {
 int[] a = { 52, 39, 67, 95, 70, 8, 25, 52 };
 new QuickSort().quickSort(a);
 for (int i : a) {
 System.out.print(i + " ");
 }
 }
}

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。如果你想了解更多相關內容請查看下面相關鏈接

相關文章

  • 詳解Java如何實現防止惡意注冊

    詳解Java如何實現防止惡意注冊

    惡意注冊通常是指使用自動化腳本或者機器人在短時間內進行大量的注冊行為,這種行為會對系統造成壓力,甚至會導致系統癱瘓。所以本文為大家總結了一些防止惡意注冊的方法,需要的可以參考一下
    2023-04-04
  • Mybatis實現分頁查詢的詳細流程

    Mybatis實現分頁查詢的詳細流程

    這篇文章主要給大家介紹了關于Mybatis實現分頁查詢的詳細流程,MyBatis是支持普通SQL查詢,存儲過程和高級映射的優(yōu)秀持久層框架,需要的朋友可以參考下
    2023-08-08
  • IDEA中如何正確快速打jar包的方式

    IDEA中如何正確快速打jar包的方式

    這篇文章主要介紹了IDEA中如何正確快速打jar包,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06
  • Java如何讀取XML文件 具體實現

    Java如何讀取XML文件 具體實現

    這篇文章主要介紹了Java如何讀取XML文件 具體實現,有需要的朋友可以參考一下
    2013-12-12
  • Java中比較運算符compareTo()、equals()與==的區(qū)別及應用總結

    Java中比較運算符compareTo()、equals()與==的區(qū)別及應用總結

    這篇文章主要給大家介紹了關于Java中比較運算符compareTo()、equals()與==的區(qū)別及應用的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面隨著小編來一起學習學習吧
    2018-09-09
  • application作用域實現用戶登錄擠掉之前登錄用戶代碼

    application作用域實現用戶登錄擠掉之前登錄用戶代碼

    這篇文章主要介紹了application作用域實現用戶登錄擠掉之前登錄用戶代碼,具有一定參考價值,需要的朋友可以了解下。
    2017-11-11
  • 利用spring-data-redis實現incr自增的操作

    利用spring-data-redis實現incr自增的操作

    這篇文章主要介紹了利用spring-data-redis實現incr自增的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • 一文帶你深入了解Guava的緩存機制

    一文帶你深入了解Guava的緩存機制

    緩存在現代編程中的作用非常大,它能提高應用性能,減少數據庫壓力,簡直就是性能優(yōu)化的利器,本文主要來和大家聊聊Google?Guava的緩存機制,感興趣的小伙伴可以了解下
    2023-12-12
  • 新版idea創(chuàng)建spring boot項目的詳細教程

    新版idea創(chuàng)建spring boot項目的詳細教程

    這篇文章給大家介紹了新版idea創(chuàng)建spring boot項目的詳細教程,本教程對新手小白友好,若根據教程創(chuàng)建出現問題導致失敗可下載我提供的源碼,在文章最后,本教程較新,文中通過圖文給大家介紹的非常詳細,感興趣的朋友可以參考下
    2024-01-01
  • Java?Web中ServletContext對象詳解與應用

    Java?Web中ServletContext對象詳解與應用

    ServletContext是一個容器,可以用來存放變量,供一個web項目中多個Servlet共享,下面這篇文章主要給大家介紹了關于Java?Web中ServletContext對象詳解與應用的相關資料,需要的朋友可以參考下
    2023-04-04

最新評論

平泉县| 台北县| 宽甸| 阿拉善右旗| 成安县| 高陵县| 江口县| 大安市| 赫章县| 斗六市| 淄博市| 宁海县| 新宁县| 波密县| 宜丰县| 双牌县| 大埔区| 寻甸| 武平县| 陇川县| 潞城市| 苍溪县| 鸡泽县| 博客| 肇东市| 襄汾县| 林甸县| 太仆寺旗| 贵溪市| 姜堰市| 浙江省| 砀山县| 肇州县| 西藏| 苗栗市| 乐业县| 兴宁市| 即墨市| 沁水县| 大英县| 新安县|