對我來說,堆排序一直神神祕祕的,直到看到了這篇文章https://www.cnblogs.com/0zcl/p/6737944.html,強烈推薦!!
文中的堆排序用的是python實現的(循環遍歷),我自己用JAVA實現了一下(循環,遞歸),特此記錄。
先寫二叉樹類
class Tree{
private int[] data;
private int tcount; //計數
private int sbindex; //sorted begin index簡寫,有序區的開始索引
public Tree(int[] arrs) {
data = arrs;
tcount = data.length;
sbindex = tcount - 1;
sort();
}
public void swap(int i, int j) {
int tem = data[i];
data[i] = data[j];
data[j] = tem;
}
public void initTopTree() { //初始化大頂堆
int bindex = tcount -2;
if(tcount%2==0) {
adjustTree(tcount/2 -1);
bindex--;
}
for(int i=bindex;i>0;i-=2) {
adjustTree((i+1)/2-1);
}
}
public void adjustTree(int index) { //根據樹節點索引遞歸調整當前節點,得到大頂堆
int lindex = 2*(index+1)-1;
if(lindex>sbindex) return; //沒有子節點,直接返回
int rindex = 2*(index+1);
int left = data[lindex];
int parent = data[index];
if(rindex>sbindex) { //只有右節點
if(left>parent) {
swap(lindex,index);
adjustTree(lindex); //遞歸
}
return; //處理完返回
}
int right = data[rindex]; //同時擁有左右節點
if(parent<left||parent<right) {
if(left<right) {
swap(index,rindex);
adjustTree(rindex); //遞歸
}else if(left>right) {
swap(index,lindex);
adjustTree(lindex); //遞歸
}
}
}
public void dosort() {
if(sbindex==0) return;
swap(0,sbindex--); //交換最大值和無序區最後一個值
adjustTree(0); //交換完之後,調整
dosort(); //遞歸
}
public void sort() {
initTopTree(); //初始化大頂堆
dosort(); //開始排序
}
@Override
public String toString() { //重寫toString方便打印
return java.util.Arrays.toString(data);
}
}
測試
public class HeapSort {
public static void main(String[] args) {
Tree tree = new Tree(new int[]{16,7,3,20,17,8});
System.out.println(tree);
}
}