日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

堆排序java实例_堆排序(示例代码)

發布時間:2025/3/15 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 堆排序java实例_堆排序(示例代码) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言:網上有很多堆排序的案例,我只想寫自己堆排序。

一:堆結構

即:一個父節點最多只能有兩個子節點(可以沒有),如下圖

圖1

? ? ? ?圖2

? ? ? ? ? 圖3

? ? ? 圖4

二: 數組與堆結構轉換

假設已知堆數組? ?int[]? a = {9,7,6,4,5,1,3,2,}? 則相應對結構如下

圖5

備注: 一個父節點(pNode? 為圖5中的7 )和兩個子節點(4(lNOde 左節點)和5(rNode 右節點))的關系

左節點: lNOde?=? 2*pNode? ?+ 1? ;

右節點 :  rNode? = 2*pNode? ? +2 ;

三:通過已知數組建立成堆結構數組

假設已知數組? ?int[] a = { 7,9,6,4,5,1,3,2};

思路:對一個已知堆結構數組(長度為n)中添加一個元素,并調整該結果使之成為新的堆結構數組(長度變成 n+1)

步驟一:獲取該數組的第一個元素 7 (a[0])為已知堆數組。

步驟二 :獲取該數組的第下一個元素9(a[1])并添加到上一個堆結構數組中,并判斷其的父節點是否大于自己,如果大于則交換父節點與自己的位置,交換后自己就在父節點的位置并把自己當成新的子節點,繼續尋找父節點直至自己小于父節點并返回。如果大于則已是堆結構返回。以此類推直至成為新的堆結構。

步驟三 :重復步驟二,直至數組最后一個元素。

java實現:

/*** 建立堆模型

*

*@parama*/

private static void buildHeat(int[] a) {for (int i = 1; i < a.length; i++) { //注意我是從數組的第二個位置(即 index = 1)開始的int parentNodeIndex =getParentNodeIndex(i);int currentIndex =i;while (parentNodeIndex >= 0) {//判斷子節點是否大于父節點

if (a[parentNodeIndex]

int temp =a[parentNodeIndex];

a[parentNodeIndex]=a[currentIndex];

a[currentIndex]=temp;

}else{// break; //步驟2 :自己小于父節點結束循環(while)已成為新的堆結構。>>>>>>>執行步驟3

}

currentIndex=parentNodeIndex; //步驟2 把自己當成新的子節點

parentNodeIndex=getParentNodeIndex(parentNodeIndex);

}

}

}

四:去堆(獲取排序)

步驟一:因為堆頂是整個堆結構中最大的數,所以我獲取堆頂的哪個數9(a[0]? 如圖5),并把堆中最后一個數2(如圖5)放入堆頂 (此時的數組長度是原來數組長度的減一)

步驟二 :調整堆結構(因為上一個步驟把 最后一個數放入如堆頂).。

調整方法:? ?獲取獲取左右子節點,先判斷是否有子節點,然后判斷兩個子節點的大小(假設9已經換成了2,當前它有兩個子節點,7(左子節點) 6 (右子節點)),獲取到最大的子節點(7),并于父節點(2)比較 ,如果子節點大于父節點,交換父節點與子節點的位置,并把當前自己成為新的父節點重復調整方法,直至沒有子節點或父節點大于所有子節點。成為新的堆結構

步驟三 :重復步驟一和二 ,直至沒有改結構中沒有子節點。

java實現

備注:代碼與步驟二的調整方法有些不同 ,因為 1)如果沒有左節點 (調整結束) 就一定不會有右節點?。2)如果有右節點就一定有左節點?。3)如果只有左節點沒有右節點?

//去除堆 》》即排序

for(int j = 0; j < a.length; j++) {int lastIndex = a.length - 1 -j;int currentIndex = 0;int temp2 = a[0]; //步驟1 : 獲取堆結構中的最大數 并與最后一個數交換位置

a[0] =a[lastIndex];

a[lastIndex]=temp2;while(true) {//獲取左節點

int leftChildNodeIndex =getLeftChildNodeIndex(currentIndex); //步驟2 獲取左節點位置if(leftChildNodeIndex >=lastIndex) { //判斷做節點是否有 有數//沒有左節點子節點 即去堆完成

for (int i = 0; i < a.length ; i++) {

System.out.print(a[i]+ ",");

}

System.out.println("沒有左節點子節點 即去堆完成");break; //步驟3

}//獲取右節點

int rightChildNodeIndex =getRightChildNodeIndex(currentIndex);if(rightChildNodeIndex >=lastIndex) { //獲取右節點//沒有右子節點 但有左節點 需要進行 交換

if (a[leftChildNodeIndex] >a[currentIndex]) {//判斷左子節點 大于父節點 需要交換位置

int temp =a[leftChildNodeIndex];

a[leftChildNodeIndex]=a[currentIndex];

a[currentIndex]=temp;

}for (int i = 0; i < a.length ; i++) {

System.out.print(a[i]+ ",");

}

System.out.println("沒有右子節點 但有左節點");break; //步驟3

}//即有左節點又有有節點//先判斷左右節點的大小 返回大節點

int whichIndexBig = a[leftChildNodeIndex] > a[rightChildNodeIndex] ?leftChildNodeIndex : rightChildNodeIndex;//判斷子節點是否大于符節點

if (a[whichIndexBig] >a[currentIndex]) {//子節點大于父節點 需要交換子父節點的位置

int temp =a[whichIndexBig];

a[whichIndexBig]=a[currentIndex];

a[currentIndex]=temp;

}//當前父節點

currentIndex =whichIndexBig; //

}

}

五 完整代碼實現如下

packagecom.jinliang.sort;public classHeatSort {public static voidmain(String[] args) {int[] a = { 7,4,6,9,5,1,3,2};//創建堆數組

buildHeat(a);for (int j = 0; j < a.length; j++) {

System.out.print(a[j]+ ",");

}

System.out.println("建隊完成");//int[] a = {42, 88, 77, 76, 66, 55, 64, 52, 45, 54, 34, 2, 32, 12, 35, 1, 22, 21, 34, 3};//去除堆 》》即排序

for(int j = 0; j < a.length; j++) {int lastIndex = a.length - 1 -j;int currentIndex = 0;int temp2 = a[0];

a[0] =a[lastIndex];

a[lastIndex]=temp2;while(true) {//獲取左節點

int leftChildNodeIndex =getLeftChildNodeIndex(currentIndex);if(leftChildNodeIndex >=lastIndex) {//沒有左節點子節點 即去堆完成

for (int i = 0; i < a.length ; i++) {

System.out.print(a[i]+ ",");

}

System.out.println("沒有左節點子節點 即去堆完成");break;

}//獲取右節點

int rightChildNodeIndex =getRightChildNodeIndex(currentIndex);if(rightChildNodeIndex >=lastIndex) {//沒有右子節點 但有左節點 需要進行 交換

if (a[leftChildNodeIndex] >a[currentIndex]) {//判斷左子節點 大于父節點 需要交換位置

int temp =a[leftChildNodeIndex];

a[leftChildNodeIndex]=a[currentIndex];

a[currentIndex]=temp;

}for (int i = 0; i < a.length ; i++) {

System.out.print(a[i]+ ",");

}

System.out.println("沒有右子節點 但有左節點");break;

}//即有左節點又有有節點//先判斷左右節點的大小 返回大節點

int whichIndexBig = a[leftChildNodeIndex] > a[rightChildNodeIndex] ?leftChildNodeIndex : rightChildNodeIndex;//判斷子節點是否大于符節點

if (a[whichIndexBig] >a[currentIndex]) {//子節點大于父節點 需要交換子父節點的位置

int temp =a[whichIndexBig];

a[whichIndexBig]=a[currentIndex];

a[currentIndex]=temp;

}//當前父節點

currentIndex =whichIndexBig;

}

}//輸出排序后的數組

for (int i = 0; i < a.length; i++) {

System.err.print(a[i]+ ",");

}

}/*** 建立堆模型

*

*@parama*/

private static void buildHeat(int[] a) {for (int i = 1; i < a.length; i++) {int parentNodeIndex =getParentNodeIndex(i);int currentIndex =i;while (parentNodeIndex >= 0) {//判斷子節點是否大于父節點

if (a[parentNodeIndex]

總結

以上是生活随笔為你收集整理的堆排序java实例_堆排序(示例代码)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。