• 堆(英语:heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵树的数组对象。堆总是满足下列性质

    • 堆中某个节点的值总是不大于或不小于其父节点的值;
    • 堆总是一棵完全二叉树。

    堆分为两中,大顶堆、小顶堆;大顶堆顾名思义就是堆的每个父元素都大于其孩子,小顶堆当然就是每个父节点都小于其子节点,数学定义如下:

    大顶堆:arr[k] >= arr[k*2+1] && arr[k] >= arr[k*2+2]

    小顶堆:arr[k] <= arr[k*2+1] && arr[k] <= arr[k*2+2]

    堆中最后一个非叶子节点为 len/2-1

    如何将一个数组构建成一个大顶堆呢?步骤如下:

    1. 将该节点和其节点比较,如果子节点值大于该节点,则交换

    2. 再次判断当前节点的子节点的子节点,直到所有节点都判断完成

    一般步骤都是从最后一层向上判断,所以就是从堆的最后一个非叶子节点开始判断,之后再将调整所有子节点,代码如下:

    package struct.tree;
    
    import java.util.Random;
    
    /**
     * 堆是一种树,完全二叉树
     * 满足如下性值:
     * 大顶堆:arr[k] >= arr[2*k+1] && arr[k] >= arr[2*k+2]
     * 小顶堆:arr[k] <= arr[2*k+1] && arr[k] <= arr[2*k+2]
     * <p>
     * 创建大顶堆
     * 从堆的最后一个非子节点开始,比较该节点和子节点大小,如果小于子节点,则交换
     * 重复,直到最后一个非子节点
     */
    public class Head {
        public static void main(String[] args) {
            int data_len = 10;
            int[] data = new int[data_len];
            Random rd = new Random();
            for (int index = 0; index < data_len; index++) {
                data[index] = rd.nextInt(10000);
            }
            createHead(data);
            for (int i = 0; i < data.length; ) {
                System.out.printf("%d	", data[i++]);
            }
    
        }
    
        public static void createHead(int[] arr) {
            // 找到最后一个非子节点
            for (int i = arr.length / 2 - 1; i >= 0; i--) {
                // 开始调整
                adjustHead(arr, i);
            }
        }
    
        /**
         * 调整堆
         *
         * @param arr
         * @param parent
         */
        public static void adjustHead(int[] arr, int parent) {
            int tmp = arr[parent];
            int child = parent * 2 + 1;
            while (child < arr.length) {
                //判断该节点下是否还有第二个子节点,找到最大的字节点
                if (child + 1 < arr.length && arr[child] < arr[child + 1]) child++;
                // 如果单前节点大于了子节点,则直接退出,否则将子节点值赋值给单前节点
                if (tmp >= arr[child]) break;
                else
                    arr[parent] = arr[child];
                //继续判断子节点的叶子
                parent = child;
                child = parent * 2 + 1;
            }
            arr[parent] = tmp;
        }
    }
  • 相关阅读:
    lambda函数
    linux 自学系列:wc命令
    linux 自学系列:chmod 权限操作
    linux 自学系列:创建、删除目录、移动、更名文件或目录
    linux 自学系列:vi、vim编辑工具
    《架构之美》学习随笔:设计第一步
    安装memcache 时提示error while loading shared libraries: libevent2.0解决办法
    《架构之美》学习随笔:保证质量
    linux 自学系列:环境变量设置
    logging模块学习笔记:logger 对象、日志等级
  • 原文地址:https://www.cnblogs.com/yunfeiqi/p/7942623.html
Copyright © 2020-2023  润新知