大根堆Java實現:


使用樹組表示的完全二叉樹的下表有如下規律:
0
1 2
3 4 5 6
7 8 ...

其中針對於k節點,其父節點是 (k-1)/2 (注意: 0節點除外)
對於k節點,其兩個兒子節點分布是: left = 2*k + 1 ; right = 2 *k + 2;

大根堆兩個主要算法:

  • 向上調整算法: 主要用於插入新元數的時候;
  • 向下調整算法: 用於從數組創建一個大根堆,或者刪除元素的時候;

最后一個節點是heapSize -1 那么最后一個節點的父節點就是最后一個非葉子節點:(完全二叉樹規律);
最后一個非葉子節點是(heapSize - 2)/2;

package BaseDataStructure;

import java.util.Arrays;

public class Heap {
        int[] arr = new int[10];
        int heapSize = 0;

        public void push(int value) {
            arr[heapSize++] = value;
            adjustUp((heapSize-2)/2);
        }

        public void poll(){

            swap(0, heapSize-1);
            heapSize --;

            adjustDown(0);

        }

        // 構建一個最大堆的過程:就是從后往前
        // 針對每個非葉子節點,做向下調整算
        // 參數是:將傳如數組,構建大根堆。
        public void buildMaxHeap(int[] _arr){
            arr = _arr;
            heapSize = _arr.length;
            // 找到非葉子節點,然后向下調整;
            for(int i = (arr.length -2)/2; i >= 0; i --){
                adjustDown(i);
            }
        }

        // 向下調整算法
        public void adjustDown(int k){
            // 非葉子節點,不用向下調整。
            // 判斷葉子節點:(堆大小是1 或 就一般的最后一個節點的父節點之后的節點都是葉子)
            if(heapSize == 1 || k > (heapSize-2)/2  )
                return;
            int left = 2*k +1, right = 2 * k + 2, largest = left;
            if(right < heapSize && arr[right] > arr[left]){
                largest = right;
            }
            if(arr[largest] > arr[k]){
                swap(largest, k);
                adjustDown(largest);
            }

        }
        
        // 向上調整算法
        public void adjustUp(int k){
            if(k < 0)
                return;
            int left = 2 * k + 1, right = 2 * k +2, largest = left;

            if(right < heapSize && arr[right] > arr[left]){
                  largest  = right;
            }

            if(arr[largest] > arr[k]){
                swap(largest, k);
                adjustUp((k-1)/2);
            }

        }
        void swap(int i, int j){
            int tmp = arr[i];
            arr[i] = arr[j];
            arr[j] = tmp;
        }

        // 排序只需要一直刪除,堆頂元素, 放到堆末尾;
        // 大根堆,就能進行從小到大排序。
        void sort(){
            for(int i = 0; i < arr.length; i++){
                poll();
            }
        }

}

import java.util.Arrays;

public class TestDemo{
    public static void main(String[] args) {
        Heap heap = new Heap();


        heap.buildMaxHeap( new int[]{3,4,5,6,9} );

        System.out.println( Arrays.toString(heap.arr) );

        heap.sort();

        System.out.println( Arrays.toString(heap.arr ));

    }
}



免責聲明!

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



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