1. 程式人生 > 實用技巧 >堆排序(HeapSort)

堆排序(HeapSort)

1.1概述

堆排序(Heapsort)是指利用堆這種資料結構所設計的一種排序演算法。堆積是一個近似完全二叉樹的結構,並同時滿足堆積的性質:即子結點的鍵值或索引總是小於(或者大於)它的父節點。

1.2描述

  • 將初始待排序關鍵字序列(R1,R2….Rn)構建成大頂堆,此堆為初始的無序區;
  • 將堆頂元素R[1]與最後一個元素R[n]交換,此時得到新的無序區(R1,R2,……Rn-1)和新的有序區(Rn),且滿足R[1,2…n-1]<=R[n];
  • 由於交換後新的堆頂R[1]可能違反堆的性質,因此需要對當前無序區(R1,R2,……Rn-1)調整為新堆,然後再次將R[1]與無序區最後一個元素交換,得到新的無序區(R1,R2….Rn-2)和新的有序區(Rn-1,Rn)。不斷重複此過程直到有序區的元素個數為n-1,則整個排序過程完成。

1.3程式碼

package heapsort;

import java.util.Arrays;

/**
 * @author xgj
 */
public class HeapSort {
    public static void main(String[] args) {
        int[] res = new int[]{1,6,5,4,6,2,7,9};
        HeapSort.heapSort(res);
        System.out.println(Arrays.toString(res));
    }

    public static void heapSort(int[] arr) {
        //1.構建大頂堆
        for (int i = arr.length / 2 - 1; i >= 0; i--) {
            //從第一個非葉子結點從下至上,從右至左調整結構
            adjustHeap(arr, i, arr.length);
        }
        //2.調整堆結構+交換堆頂元素與末尾元素
        for (int j = arr.length - 1; j > 0; j--) {
            //將堆頂元素與末尾元素進行交換
            swap(arr, 0, j);
            //重新對堆進行調整
            adjustHeap(arr, 0, j);
        }

    }


    public static void adjustHeap(int[] arr, int i, int length) {
        //先取出當前元素i
        int temp = arr[i];
        //從i結點的左子結點開始,也就是2i+1處開始
        for (int k = i * 2 + 1; k < length; k = k * 2 + 1) {
            //如果左子結點小於右子結點,k指向右子結點
            if (k + 1 < length && arr[k] < arr[k + 1]) {
                k++;
            }
            //如果子節點大於父節點,將子節點值賦給父節點(不用進行交換)
            if (arr[k] > temp) {
                arr[i] = arr[k];
                i = k;
            } else {
                break;
            }
        }
        //將temp值放到最終的位置
        arr[i] = temp;
    }

    public static void swap(int[] arr, int a, int b) {
        int temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }

}

1.4分析

最佳情況:T(n) = O(nlogn) 最差情況:T(n) = O(nlogn) 平均情況:T(n) = O(nlogn)