zoukankan      html  css  js  c++  java
  • 大根堆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 ));
    
        }
    }
    
    
    
  • 相关阅读:
    RGB888转RGB666
    bmp文件格式详细解析
    Qt 5简介
    IntelliJ IDEA 快捷键
    猫猫学iOS之小知识之_xcode插件的删除方法_自己主动提示图片插件KSImageNamed有时不灵_分类或宏之类不能自己主动提示,
    sql server 2008出现远程过程调用失败
    Oracle-31-对视图DML操作
    uva 11127(暴力)
    各种排序算法的分析与实现
    我的Android进阶之旅------&gt;怎样解决Android 5.0中出现的警告: Service Intent must be explicit:
  • 原文地址:https://www.cnblogs.com/sidewinder/p/13733329.html
Copyright © 2011-2022 走看看