堆操作(2)-創建一個最大堆


一、最大堆建立

給定N個元素,按照最大堆的要求將元素放入數組中。

兩種做法:

  1. 通過插入,依次將N個元素插入一個空堆中,復雜度為nlogn。
  2. 線性復雜度建立堆
    1. 先將N個元素按照順序存入,先滿足完全二叉樹的特性
    2. 調整各個節點,讓其滿足最大堆的特性

本文主要介紹第二種方法,線性復雜度創建堆。

二、線性復雜度創建堆

默認創建一個完全二叉樹

從最后一個節點的父節點【第一個父節點】(87)開始調整。87大於9。默認不變,當前子樹是一個堆。

第二個父節點30。最大子節點為72。把72個30繼續互換,當前子樹是一個堆。

第三個父節點83。最大子節點為91。把91和83進行互換,當前子樹也是一個堆。

三次交換后,樹的結構如下。

從43開始調整。87大於43,互換,當前子樹是一個堆。

從66開始調整,91大於66進行互換。83大於66,再次進行互換,當前子樹是一個堆。

最后調整根節點;91和79互換。83和79進行互換,至此。整顆樹都變成了一個堆。

代碼

public static void percDown(HeapStruct heapStruct, int rootIndex) {
        Integer[] elements = heapStruct.getElements();
        Integer rootValue = elements[rootIndex];
        int parentIndex = rootIndex;
        while (parentIndex * 2 <= heapStruct.getSize() - 2) {
            int childIndex = parentIndex * 2 + 1;
            if (childIndex < heapStruct.getSize() - 1 && elements[childIndex].compareTo(elements[childIndex + 1]) < 0) {
                childIndex = childIndex + 1;//找到最大的一個兒子
            }
            if (rootValue.compareTo(elements[childIndex]) > 0) {//當前節點大於最大的兒子節點。
                break;
            } else {
                elements[parentIndex] = elements[childIndex];//和兒子節點進行替換。
                parentIndex = childIndex;
            }
        }
        elements[parentIndex]=rootValue;
    }
    @Test
    public void createHeap() {
        HeapStruct heapStruct = HeapUtil.initHeap(20);
        for (int i = 0; i < 11; i++) {
            heapStruct.getElements()[i] = i;//初始化一個數組。
        }
        for (int n = (heapStruct.getSize() - 1) / 2; n >= 0; n--) {//一個個遍歷父節點,使得當前父節點所在的子樹變成一個堆
            HeapUtil.percDown(heapStruct, n);
        }
    }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM