<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          圖解堆排序

          共 2624字,需瀏覽 6分鐘

           ·

          2021-03-17 06:23


          程序員常用的IDEA插件:https://github.com/silently9527/ToolsetIdeaPlugin

          完全開源的淘客項目:https://github.com/silently9527/mall-coupons-server

          微信公眾號:貝塔學(xué)Java

          前言

          在上一篇中我們一起使用二叉堆實現(xiàn)了優(yōu)先級隊列,假如我們從構(gòu)建好的優(yōu)先級隊列中持續(xù)調(diào)用刪除最?。ɑ蛘咦畲螅?,把結(jié)果輸出到另一個數(shù)組中,那么就可以把數(shù)組的所有元素進(jìn)行排序,這就是本篇我們需要學(xué)習(xí)的堆排序。在看本篇之前需要先看下前一篇《原來實現(xiàn)優(yōu)先級隊列如此簡單》

          堆排序的過程主要有兩個階段:

          • 把原始數(shù)據(jù)構(gòu)造成一個有序堆(構(gòu)造堆)
          • 從堆中按照遞減順序取出所有元素就可以得到排序結(jié)果(下沉排序)

          開始之前,我們需要把上一篇中的sink()方法修改一下;

          保證我們在進(jìn)行排序的時候直接使用原始的數(shù)組,無需建立一個輔助數(shù)組浪費(fèi)空間;由于我們需要動態(tài)的縮小堆的大小,需要把size通過參數(shù)傳入;

          其次我們數(shù)組的下標(biāo)是從0開始的,與之前的優(yōu)先級排序有些差別,對于k節(jié)點的左邊節(jié)點下標(biāo)是2k+1,右邊下標(biāo)是2k+2

          private void sink(Comparable[] queue, int k, int size) {
              while (2 * k + 1 < size) {
                  int i = 2 * k + 1;
                  if (i < size - 1 && less(queue[i], queue[i + 1])) {
                      i++;
                  }
                  if (less(queue[i], queue[k])) {
                      break;
                  }
                  exch(queue, i, k);
                  k = i;
              }
          }

          構(gòu)造堆

          把一個輸入的數(shù)組構(gòu)建成一個堆有序,我們有兩種方式:

          1. 從左向右遍歷數(shù)組,然后把調(diào)用swim()上浮操作保證指針左邊的元素都是堆有序的,就和優(yōu)先級隊列的插入過一樣
          2. 由于數(shù)組中的每個位置已經(jīng)是堆的節(jié)點,我們可以從右向左調(diào)用sink()下沉操作構(gòu)造堆,這個過程我們可以跳過子堆為1的元素,所以我們只需要掃描數(shù)組的一半元素。這種方式會更高效。

          例如:輸入數(shù)組 a[]={8,3,6,1,4,7,2}

          下沉排序

          下沉是堆排序的第二個階段,我們把最大元素刪除,然后放入到堆縮小后數(shù)組中空出來的位置,當(dāng)操作完成所有的元素之后,整個數(shù)組將會是有序的

          下沉排序演示過程(圖未完全畫完):

          堆排序代碼實現(xiàn)

          @Override
          public void sort(Comparable[] array) {
              int size = array.length;
              for (int k = size / 2; k >= 0; k--) {
                  sink(array, k, size);
              }
              while (size > 0) {
                  exch(array, 0, --size);
                  sink(array, 0, size);
              }
          }

          文中所有源碼已放入到了github倉庫https://github.com/silently9527/JavaCore

          最后(點關(guān)注,不迷路)

          文中或許會存在或多或少的不足、錯誤之處,有建議或者意見也非常歡迎大家在評論交流。

          最后,寫作不易,請不要白嫖我喲,希望朋友們可以點贊評論關(guān)注三連,因為這些就是我分享的全部動力來源??

          瀏覽 63
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  蜜桃在线无码精品秘 入口欧 | 三级片无码在线播放 | 巨大乳人妻中文字幕 | 琪琪婷婷五月色综合 | 唐嫣一区二区三区在线 |