Java資料結構(十一)—— 堆及堆排序
阿新 • • 發佈:2020-11-29
堆
堆基本介紹
-
堆排序是利用堆這種資料結構而設計的一種排序演算法,堆排序是一種選擇排序,最壞,最好,平均時間複雜度都是O(nlogn),不穩定的排序
-
堆是具有以下性質的完全二叉樹:每個節點的值都大於或等於其左右孩子節點的值稱為大頂堆
-
小於或等於左右孩子節點的值稱為小頂堆
堆排序
基本思想
-
將待排序的序列構造成一個大頂堆(陣列)
-
此時 ,整個序列的最大值就是堆頂的根節點
-
將其與末尾元素進行交換,此時末尾為最大值
-
然後將剩餘n-1個元素重新構造成一個堆,這樣就會得到n個元素的次小值。如此反覆執行便能得到一個有序序列
基本步驟
-
構造初始堆,順序存放
-
從最後一個非葉子節點:arr.length/2-1,開始,從左至右,從下至上進行調整
-
找到第二個非葉子節點,比較其與子節點的大小進行交換
-
這會導致其交換子樹的順序混亂則繼續向下交換
-
堆頂出堆,針對剩餘元素重複上列步驟
程式碼實現
package com.why.tree;
import java.util.Arrays;
import java.util.jar.JarEntry;
/**
* @Description TODO 堆排序
* @Author why
* @Date 2020/11/26 18:05
* Version 1.0
**/
public class HeapSort {
public static void main(String[] args) {
int[] arr = {4,6,8,5,9};
heapSort(arr);
}
/**
* 堆排序
* @param arr
*/
public static void heapSort(int[] arr){
int temp = 0;
//調整成大頂堆
for (int i = arr.length/2 - 1; i >= 0 ; i--) {
adjustHeap(arr,i,arr.length);
}
//將堆頂元素與末尾元素交換,將最大元素沉到陣列末端
for (int i = arr.length - 1; i > 0; i--) {
//交換
temp = arr[i];
arr[i] = arr[0];
arr[0] = temp;
adjustHeap(arr,0, i);
}
System.out.println(Arrays.toString(arr));
}
/**
* 將陣列(二叉樹)調整為大頂堆
* 完成將i對應的的非葉子節點調整成大頂堆
* 自下向上調整
* @param arr 待調整的陣列
* @param i 表示非葉子節點在陣列中的索引
* @param lengt 表示對多少個元素進行調整,lengt逐漸減小
*/
public static void adjustHeap(int[] arr,int i,int lengt){
//取出當前的值,儲存至臨時變數
int temp = arr[i];
//開始調整
//j = i * 2 + 1,j是i節點的左子節點
for (int j = i * 2 + 1; j < lengt; j = j * 2 + 1) {
if(j + 1< lengt &&arr[j] < arr[j+1]){//左子節點小於右子節點
j++;//j指向右子節點
}
if (arr[j] > temp){//如果子節點大於父節點
arr[i] = arr[j];