zoukankan      html  css  js  c++  java
  • 堆(英语: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;
        }
    }
  • 相关阅读:
    Android渐变GradientDrawable叠加组合环ring
    72.spring boot讨论群【从零开始学Spring Boot】
    71.mybatis 如何获取插入的id【从零开始学Spring Boot】
    Android GradientDrawable的XML实现
    服务器端架构及实战 — C#分享
    70.打印所有Spring boot载入的bean【从零开始学Spring Boot】
    69. JPA实体Bean的生命周期【从零开始学Spring Boot】
    Android版网易云音乐唱片机唱片磁盘旋转及唱片机机械臂动画关键代码实现思路
    服务器架构及实战(架构篇)- PHP建站
    创建MyOffice项目
  • 原文地址:https://www.cnblogs.com/yunfeiqi/p/7942623.html
Copyright © 2011-2022 走看看