排序算法---堆排序(Heap Sort)

堆排序算法,基于選擇排序的思想,利用堆結構的性質來完成對數據的排序。

前提準備:

  1. 什么是堆結構:
    堆數據結構是一種數組對象,它可以被視為一科完全二叉樹結構。它的特點是父結點的值大于(小于)兩個子結點的值(分別稱為大頂堆和小頂堆)


    堆示意圖
  2. 堆結構的性質:
    對于第n個結點而言 --- 它的父結點下標 i = (n-1)/ 2,左子結點 left = 2n+1,右子結點 right =2n+2

結構圖

算法基本思想:

1. 構建堆(大頂堆或小頂堆,現以大頂堆為例):

  • 首先從最后一個結點開始,找到它的父結點,在父結點和父結點的左右結點中,選出最大的值,與父節點交換。
  • 然后對倒數第二個結點執行同樣的操作
  • 這樣直到根結點的時候,根結點變成了所以數據中最大的值。

2. 替換根結點,重建堆:

  • 將根結點與最后一個結點的數據交換,在把倒數第二個結點視為最后一個結點,重新建堆。
  • 重復上述的操作。最終,數據排序完成。

代碼實現:

import java.util.Arrays;

/**
 * Created by noonbiteun
 * Date: 2017/7/31
 */
public class HeapSort {
    //建堆
    private static void heapConstruct(int[] arr, int last) {
        int tmp;
        for (int parent = (last - 1) / 2; parent >= 0; parent = (last-1) / 2) {
            if (2*parent+1 < last) {
                //第last個節點為右子樹
                if (arr[last - 1] < arr[last]) {
                    //大的數據往前移
                    tmp = arr[last];
                    arr[last] = arr[last - 1];
                    arr[last - 1] = tmp;
                } else {
                    last--;
                }
            }
            if (arr[parent] < arr[last]) {
                //大的數據移到父節點
                tmp = arr[last];
                arr[last] = arr[parent];
                arr[parent] = tmp;
            }
            last--;
        }
    }

    private static void sort(int[] arr) {
        int last = arr.length - 1;
        int tmp;
        System.out.println("原始順序: " + Arrays.toString(arr));
        for (int i = 0; i < arr.length; i++) {
            heapConstruct(arr, last);
            //第一個和最后一個交換
            tmp = arr[0];
            arr[0] = arr[last];
            arr[last] = tmp;
            last--;
            System.out.println("第" + i + "趟排序:" + Arrays.toString(arr));
        }
    }

    public static void main(String[] args) {
        int[] arr = new int[10];
        //初始化數組
        for (int i = 0; i < 10; i++) {
            arr[i] = (int) (Math.random() * (100 + 1));
        }

        HeapSort.sort(arr);
    }
}

輸出結果:

運行結果

小結分析:

經過兩三天的不斷學習,感覺這方面在一點點的進步,今天的這個堆排序,只看了書上寫的算法思想之后,馬上就能寫出來,感覺比前幾天對著一個冒泡排序死磕了一個小時要進步很大了,加油。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 課程介紹 先修課:概率統計,程序設計實習,集合論與圖論 后續課:算法分析與設計,編譯原理,操作系統,數據庫概論,人...
    ShellyWhen閱讀 2,357評論 0 3
  • 概述:排序有內部排序和外部排序,內部排序是數據記錄在內存中進行排序,而外部排序是因排序的數據很大,一次不能容納全部...
    每天刷兩次牙閱讀 3,743評論 0 15
  • 1.插入排序—直接插入排序(Straight Insertion Sort) 基本思想: 將一個記錄插入到已排序好...
    依依玖玥閱讀 1,282評論 0 2
  • 概述 排序有內部排序和外部排序,內部排序是數據記錄在內存中進行排序,而外部排序是因排序的數據很大,一次不能容納全部...
    蟻前閱讀 5,220評論 0 52
  • 周日去看了《修女也瘋狂》,據說是百老匯原班人馬,全國巡演之前在廣州排練了挺久。 演的非常好! 世紀劇院應該算是比較...
    請不要叫我小Helen閱讀 748評論 0 0