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

Java編程中快速排序算法的實(shí)現(xiàn)及相關(guān)算法優(yōu)化

 更新時(shí)間:2016年05月04日 16:06:57   作者:然則  
這篇文章主要介紹了Java編程中快速排序算法的實(shí)現(xiàn)及相關(guān)算法優(yōu)化,快速排序算法的最差時(shí)間復(fù)雜度為(n^2),最優(yōu)時(shí)間復(fù)雜度為(n\log n),存在優(yōu)化的空間,需要的朋友可以參考下

時(shí)間復(fù)雜度

平均情況:O(nlgn)
最壞情況:O(n*n),發(fā)生在當(dāng)數(shù)據(jù)已經(jīng)是排序狀態(tài)時(shí)
快排算法的基本原理

1、從數(shù)據(jù)中選取一個(gè)值a[i]作為參考
2、以a[i] 為參考,將數(shù)據(jù)分成2部分:P1、P2,P1中的數(shù)據(jù)全部≤a[i],P2中的數(shù)據(jù)全部>a[i],數(shù)據(jù)變?yōu)椋鸓1}{a[i]}{P2}}
3、將P1、P2重復(fù)上述步驟,直到各部分中只剩1個(gè)數(shù)據(jù)
4、數(shù)據(jù)完成升序排列

基本示例:

原始數(shù)據(jù):

  {3,9,8,5,2,1,6}

第1步:選取第1個(gè)數(shù)據(jù):3
第2步:將數(shù)據(jù)分成2部分,左邊≤3,右邊大于>3:

  {2,1} {3} {9,8,5,6}

第3步:將各部分重復(fù)以上步驟,直到每部分只剩1個(gè)數(shù)據(jù):

  {2,1} => {1} {2}
  {9,8,5,6} => {8,5,6} {9}=> {5,6} {8} {9}=> {5} {6} {8} {9}

第4步:數(shù)據(jù)完成升序排列:

  {1} {2} {3} {5} {6} {8} {9}

程序中數(shù)據(jù)通常保存在數(shù)組中,以int類型的數(shù)組為例,可以將上面的步驟寫成一個(gè)quickSort函數(shù)原型:

quickSort(int begin, int end) { 
//begin為數(shù)組的第一個(gè)數(shù)據(jù)的索引值,end為數(shù)組的最后一個(gè)數(shù)據(jù)的索引值+1
  //如果只有1個(gè)數(shù)據(jù)或0個(gè)數(shù)據(jù),則程序返回
  if( begin == end || begin == (end-1) ) return; 
  int p = in[begin];//p為選擇的參考數(shù)據(jù),選擇第一個(gè)數(shù)據(jù)
  int a = begin +1; //a作為2部分?jǐn)?shù)據(jù)分界線的索引值
  int b = a;//b為待比較的數(shù)據(jù)的索引值
  for( ; b < end; b++) {//將數(shù)組中的各個(gè)數(shù)據(jù)依次與參考數(shù)據(jù)進(jìn)行比較
    if( in[b] < p) { //如果該數(shù)據(jù)<參考數(shù)據(jù)則將其移動(dòng)到左邊
      if(a == b){a++; continue;} //如果該數(shù)據(jù)已經(jīng)在左邊則不動(dòng)
      int temp = in[a];//將數(shù)據(jù)移動(dòng)到左邊
      in[a] = in[b];
      in[b] = temp;
      a++;//將分界線右移
    }
  }
  in[begin] = in[a-1];//講參考值移動(dòng)到2組數(shù)據(jù)中間
  in[a-1] = p;
  if( a-1 > begin){ // 如果左邊有數(shù)據(jù)則將其重復(fù)上述步驟
    quickSort(begin, a);
  } 
  if( end-1 > a ) {// 如果右邊有數(shù)據(jù)則將其重復(fù)上述步驟
    quickSort(a, end);
  } 
  return; // 如果無(wú)數(shù)據(jù)返回
}

算法優(yōu)化
上面這個(gè)快速排序算法可以說(shuō)是最基本的快速排序,因?yàn)樗](méi)有考慮任何輸入數(shù)據(jù)。但是,我們很容易發(fā)現(xiàn)這個(gè)算法的缺陷:這就是在我們輸入數(shù)據(jù)基本有序甚至完全有序的時(shí)候,這算法退化為冒泡排序,不再是O(n㏒n),而是O(n^2)了。
究其根源,在于我們的代碼實(shí)現(xiàn)中,每次只從數(shù)組第一個(gè)開(kāi)始取。如果我們采用“三者取中”,即arr[low],arr[high],arr[(low+high)/2]三者的中值作為樞軸記錄,則可以大大提高快速排序在最壞情況下的性能。但是,我們?nèi)匀粺o(wú)法將它在數(shù)組有序情形下的性能提高到O(n)。還有一些方法可以不同程度地提高快速排序在最壞情況下的時(shí)間性能。

此外,快速排序需要一個(gè)遞歸棧,通常情況下這個(gè)棧不會(huì)很深,為log(n)級(jí)別。但是,如果每次劃分的兩個(gè)數(shù)組長(zhǎng)度嚴(yán)重失衡,則為最壞情況,棧的深度將增加到O(n)。此時(shí),由棧空間帶來(lái)的空間復(fù)雜度不可忽略。如果加上額外變量的開(kāi)銷,這里甚至可能達(dá)到恐怖的O(n^2)空間復(fù)雜度。所以,快速排序的最差空間復(fù)雜度不是一個(gè)定值,甚至可能不在一個(gè)級(jí)別。
為了解決這個(gè)問(wèn)題,我們可以在每次劃分后比較兩端的長(zhǎng)度,并先對(duì)短的序列進(jìn)行排序(目的是先結(jié)束這些棧以釋放空間),可以將最大深度降回到O(㏒n)級(jí)別。

這里提出對(duì)快速排序的3點(diǎn)優(yōu)化思路:
對(duì)于小數(shù)組,可以采用插入排序,避免遞歸調(diào)用。例如,當(dāng)if(hi <= lo + M)時(shí),就可以轉(zhuǎn)到插入排序。
采用子數(shù)組的一部分元素的中位數(shù)來(lái)切分?jǐn)?shù)組。這樣做得到的切分更好,但代價(jià)是需要計(jì)算中位數(shù)。
如果數(shù)組中含有大量的重復(fù)元素,可以采用三向切分。將數(shù)組切分為三部分,分別對(duì)應(yīng)于小于、等于和大于切分元素的數(shù)組元素。代碼實(shí)現(xiàn)如下:

  private static void sort1(int[] a, int lo, int hi) {
  if (hi <= lo)
    return;
  int lt = lo, i = lo + 1, gt = hi;
  int v = a[lo];
  while (i <= gt) {
    if (a[i] < v) {
      swap(a, lt++, i++);
    } else if (a[i] > v) {
      swap(a, i, gt--);
    } else {
      i++;
    }
    sort(a, lo, lt - 1);
    sort(a, gt + 1, hi);
  }
}

相關(guān)文章

  • java synchronized 鎖機(jī)制原理詳解

    java synchronized 鎖機(jī)制原理詳解

    synchronized關(guān)鍵字是JAVA中常用的同步功能,提供了簡(jiǎn)單易用的鎖功能。這篇文章主要介紹了Java中synchronized關(guān)鍵字引出的多種鎖問(wèn)題,需要的朋友可以參考下
    2021-08-08
  • 關(guān)于java中可變長(zhǎng)參數(shù)的定義及使用方法詳解

    關(guān)于java中可變長(zhǎng)參數(shù)的定義及使用方法詳解

    下面小編就為大家?guī)?lái)一篇關(guān)于java中可變長(zhǎng)參數(shù)的定義及使用方法詳解。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-12-12
  • java日志LoggerFactory.getLogger的用法及說(shuō)明

    java日志LoggerFactory.getLogger的用法及說(shuō)明

    這篇文章主要介紹了java日志LoggerFactory.getLogger的用法及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • CentOS 7快速安裝jdk

    CentOS 7快速安裝jdk

    這篇文章主要為大家詳細(xì)介紹了CentOS 7快速安裝jdk的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • Spring Security 中如何讓上級(jí)擁有下級(jí)的所有權(quán)限(案例分析)

    Spring Security 中如何讓上級(jí)擁有下級(jí)的所有權(quán)限(案例分析)

    這篇文章主要介紹了Spring Security 中如何讓上級(jí)擁有下級(jí)的所有權(quán)限,本文通過(guò)案例分析給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • springboot實(shí)現(xiàn)string轉(zhuǎn)json json里面帶數(shù)組

    springboot實(shí)現(xiàn)string轉(zhuǎn)json json里面帶數(shù)組

    這篇文章主要介紹了springboot實(shí)現(xiàn)string轉(zhuǎn)json json里面帶數(shù)組,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • IntelliJ IDEA使用git初始化倉(cāng)庫(kù)的使用方法

    IntelliJ IDEA使用git初始化倉(cāng)庫(kù)的使用方法

    這篇文章主要介紹了IntelliJ IDEA使用git初始化倉(cāng)庫(kù)的使用方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • 解讀JSONArray刪除元素的兩種方式

    解讀JSONArray刪除元素的兩種方式

    這篇文章主要介紹了解讀JSONArray刪除元素的兩種方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • SpringBoot應(yīng)用jar包啟動(dòng)原理詳解

    SpringBoot應(yīng)用jar包啟動(dòng)原理詳解

    本文主要介紹了SpringBoot應(yīng)用jar包啟動(dòng)原理詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-03-03
  • SparkSQL開(kāi)窗函數(shù)分析使用示例

    SparkSQL開(kāi)窗函數(shù)分析使用示例

    開(kāi)窗函數(shù)的引入是為了既顯示聚集前的數(shù)據(jù),又顯示聚集后的數(shù)據(jù)。即在每一行的最后一列添加聚合函數(shù)的結(jié)果。開(kāi)窗用于為行定義一個(gè)窗口,它對(duì)一組值進(jìn)行操作,不需要使用 GROUP BY 子句對(duì)數(shù)據(jù)進(jìn)行分組,能夠在同一行中同時(shí)返回基礎(chǔ)行的列和聚合列
    2023-01-01

最新評(píng)論

贵德县| 景德镇市| 子洲县| 紫金县| 石河子市| 渭南市| 军事| 固镇县| 隆回县| 新宁县| 新乡县| 汝阳县| 新昌县| 通州区| 兴海县| 邵武市| 乌拉特后旗| 台南市| 红原县| 泗水县| 阜城县| 郁南县| 泰顺县| 宾川县| 平度市| 威信县| 浮梁县| 岳普湖县| 乐平市| 安宁市| 盱眙县| 尼勒克县| 江西省| 汝州市| 梧州市| 梧州市| 贺州市| 德阳市| 布尔津县| 徐州市| 驻马店市|