• 数据结构之堆


    1.堆的构建(大根堆):

    package com.hfm.util;

    import java.util.Arrays;

    public class Heap {
    int arr[];

    public Heap(int[] arr) {
    this.arr = arr;
    print(arr);
    build(arr,arr.length-1,arr.length-1);
    print(arr);
    }

    private int getHeight(int arr[]){
    return (int)Math.ceil(Math.log(1+arr.length)/Math.log(2));
    }

    private static void print(int arr[]){
    int height = 0,count = 0;
    System.out.println();
    while(count<arr.length){
    int num = ((int) Math.pow(2, height));
    for(int i=0;i<num&&(count<arr.length);i++){
    System.out.print(arr[count]+" ");
    count ++;
    }
    height++;
    System.out.println();
    }
    System.out.println();
    }

    private void swap(int arr[],int x,int y){
    arr[x] += arr[y];
    arr[y] = arr[x] - arr[y];
    arr[x] = arr[x] - arr[y];
    }

    private void sort(){
    for (int i = arr.length-1; i >0; i--) {
    swap(arr,0,i);
    adjust(arr,i-1,i-1);
    }
    print(arr);
    }

    private void adjust(int arr[],int end,int visited){ // 大根堆的调整
    if(visited==0)
    return;
    int parent = ((int) Math.ceil(end / 2.0))-1>-1? ((int) Math.ceil(end / 2.0))-1:0,last = 0;
    while (parent>-1){
    if(arr[end]>arr[parent]){
    swap(arr,end,parent);
    last = parent;
    end = parent;
    parent = ((int) Math.ceil(parent / 2.0))-1>-1? ((int) Math.ceil(parent / 2.0))-1:0;
    continue;
    }
    break;
    }
    //交换叶子节点最大值和当前值
    int res[] = null;
    while((res = maxLeaf(arr,last))[0]!=-Integer.MAX_VALUE){
    if(res[0] != -Integer.MAX_VALUE){
    if(arr[last]<arr[res[1]]&&res[1]<end){
    swap(arr,res[1],last);
    }
    last = res[1];
    }
    }
    adjust(arr,--visited,visited);
    }

    /**
    * 大根堆的构建,根据传入的数组进行构建,使用递归的思想
    * 从叶子节点开始,从第一个非叶子节点开始往前依次调整,直到根节点
    * @param arr
    * @param curNotLeaf 当前节点下标
    * @param visited 当前被访问或被处理过的节点下标
    */
    private void build(int arr[],int curNotLeaf,int visited){ // 大根堆的构建
    if(visited==0)
    return;
    int parent = ((int) Math.ceil(curNotLeaf / 2.0))-1>-1? ((int) Math.ceil(curNotLeaf / 2.0))-1:0,//当前节点的父节点下标
    last = 0; //记录下交换的最后位置的下标,方便后续从该节点开始向下回溯
    while (parent>-1){//向上寻找,直到父节点下表对应的值已经满足大根堆的条件为止
    if(arr[curNotLeaf]>arr[parent]){
    swap(arr,curNotLeaf,parent);
    last = parent;
    curNotLeaf = parent;
    parent = ((int) Math.ceil(parent / 2.0))-1>-1? ((int) Math.ceil(parent / 2.0))-1:0;
    continue;
    }
    break;
    }
    //交换叶子节点最大值和当前值
    int res[] = null;
    while((res = maxLeaf(arr,last))[0]!=-Integer.MAX_VALUE){
    if(res[0] != -Integer.MAX_VALUE){
    if(arr[last]<arr[res[1]]){
    swap(arr,res[1],last);
    }
    last = res[1];
    }
    }
    build(arr,--visited, visited);
    }

    /**
    * 去除当前节点的子节点中最大值和它对应的下标
    * 若无子节点,则返回最小整数
    * @param arr
    * @param index
    * @return
    */
    private int[] maxLeaf(int arr[],int index){
    if(index*2+1>arr.length-1)
    return new int[]{-Integer.MAX_VALUE,-Integer.MAX_VALUE};
    if(index*2+2>arr.length-1)
    return new int[]{arr[index*2+1],index*2+1};
    else
    return arr[index*2+1]>=arr[index*2+2]?new int[]{arr[index*2+1],index*2+1}:new int[]{arr[index*2+2],index*2+2};
    }

    public static void main(String[] args) {
    Heap heap = new Heap(new int[]{5,8,13,2,7,12,15,2});
    heap.sort();
    }
    }

     2.堆的典型应用:堆排序,top-k问题等

  • 相关阅读:
    vue中 key 值的作用
    v-on可以监听多个方法吗?
    vue常用的修饰符
    v-if和v-show的区别
    Vue和其他框架的区别
    Vue面试题总结——目录
    vue是一个渐进式的框架,我是这么理解的
    原生JS封装创建多级菜单函数
    如何使用mongodb(建立原型,连接数据库)
    Hive 的安装与配置
  • 原文地址:https://www.cnblogs.com/g177w/p/14726537.html
Copyright © 2020-2023  润新知