排序演算法 三 堆排序

2021-08-22 04:46:34 字數 2060 閱讀 9538

1.heap.class

package cn.sort.heap;

/** * 堆排序實現:公升序排序

*@author ly

* */

public

class

heap

system.out.println();

}/**

* 向下調整:先拿左右子樹進行比較,看誰比較大,

* 然後再拿大的與父結點進行比較,若孩子結點比較大,則大孩子與父結點交換,繼續調整

*@param arr

*@param size

*@param index

*/private

static

void

adjustdown(integer arr, int size, int index)

// 然後再拿大的與父結點進行比較,若孩子結點比較大,則大孩子與父結點交換

if(arr[child] > arr[parent])

else

// 交換後破壞堆結構,繼續調整,直到滿足堆

parent = child;

child = 2 * parent + 1;

}return;

}/**

* 建大堆 :

* 下沉式調整,需要從後往前遍歷從最後乙個非葉子結點開始遍歷 (size - 1 - 1) / 2

* size - 1 表示最後乙個元素的下標

* 拿著這個下標-1 / 2 就得到當前元素的父節點

*@param arr 陣列

*@param size 陣列大小

*/private

static

void

createheap(integer arr, int size)

// 下沉式調整,需要從後往前遍歷

// 從最後乙個非葉子結點開始遍歷 (size - 1 - 1)/ 2

// size - 1 表示最後乙個元素的下標

// 拿著這個下標-1 / 2 就得到當前元素的父節點

int parent = (size - 1 - 1) / 2;

for(int i = parent; i >= 0; i--)

}/**

* 堆刪:將堆頂元素與最後乙個元素交換,然後對堆頂(從0下標)進行向下調整

*@param arr 陣列

*@param size 陣列大小

*/private

static

void

if(size <= 1)

// 交換堆頂元素與最後乙個元素

int tmp = arr[0];

arr[0] = arr[size - 1];

arr[size - 1] = tmp;

// 關鍵在於 size - 1,相當於刪除了乙個元素,對交換後的最後元素不處理

adjustdown(arr, size - 1, 0);

}/**

* 堆排序:公升序

*@param arr 陣列

*/public

static

void

heapsort(integer arr)

int size = arr.length;

// 1. 建大堆

createheap(arr, size);

// 2. 迴圈刪除堆頂元素,最大元素依次到了隊尾

for(int i = 0; i < size; i++) }}

2.test.class

package cn.sort.heap;

public

class test ;

int size = arr.length;

heap.heapsort(arr);

heap.printarr(arr, size);}}

3.截圖

選擇排序(三) 堆排序

這樣,還剩下兩個問題 1.如何將乙個交換後的無序區調整為大根堆 2.如何在排序之前建立那個初始的大根堆。而第二個問題是可以通過第乙個問題的解決而解決的。1.如何將乙個交換後的無序區調整為大根堆?由於進行元素交換前,無序區是乙個大根堆,即左子樹和右子樹都是大根堆,所以根節點變化後左右子樹仍然都是大根堆...

選擇排序(三) 堆排序

這樣,還剩下兩個問題 1.如何將乙個交換後的無序區調整為大根堆 2.如何在排序之前建立那個初始的大根堆。而第二個問題是可以通過第乙個問題的解決而解決的。1.如何將乙個交換後的無序區調整為大根堆?由於進行元素交換前,無序區是乙個大根堆,即左子樹和右子樹都是大根堆,所以根節點變化後左右子樹仍然都是大根堆...

演算法學習(三)堆排序

要弄清楚堆排序,我們首先要懂得以下兩點 1 邏輯上的結構,怎麼樣才是乙個堆。2 儲存上的結構,乙個堆儲存起來的結構是怎麼樣的。一般來講,堆排序中的 堆 指的是二叉堆,一種完全二叉樹的結構,每個父結點最多只有兩個子結點,且滿足兩點 1 父結點總是大於 小於 其兩個子結點 大於的,我們叫最大堆,小於的,...