zoukankan      html  css  js  c++  java
  • 最大堆


    /**
    * 堆通常是一个可以被看做一棵树的数组对象。
    * 堆总是满足下列性质:
    * 堆中某个节点的值总是不大于或不小于其父节点的值;
    * 堆总是一棵完全二叉树。
    * 将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆
    */
    public class MaxHeap {

    public static class MyMaxHeap {

    public int[] heap;

    public final int limit;

    public int heapSize;

    public MyMaxHeap(int limit) {
    this.heap = new int[limit];
    this.limit = limit;
    }

    /**
    * 往最大堆中添加一个元素
    *
    * @param value 元素
    */
    public void push(int value) {
    if (isFull()) {
    System.out.println("the heap is full");
    return;
    }
    heap[heapSize] = value;
    heapInsert(heapSize++);
    }

    /**
    * 往堆中添加一个元素,同时必须是最大堆
    *
    * @param index 新添加的元素的位置
    */
    public void heapInsert(int index) {
    int pIndex = 0;
    // 此处 ((index - 1) / 2) 和 ((index - 1) >> 1) 计算结果是不一样的,当index=0,前者是0,后者是-1
    while (heap[index] > heap[pIndex = ((index - 1) / 2)]) {
    swap(heap, index, pIndex);
    index = pIndex;
    }
    }

    /**
    * 弹出堆中的最大值,同时把该值从堆中移除掉
    *
    * @return 最大值
    */
    public int pop() {
    if (isEmpty()) {
    System.out.println("the heap is empty");
    return 0;
    }
    int max = heap[0];
    swap(heap, 0, --heapSize);
    heapify(heap, 0, heapSize);
    return max;
    }

    /**
    * 修改了一个元素之后,保持最大堆
    *
    * @param arr 堆
    * @param index 修改的元素位置
    * @param heapSize 堆大小
    */
    public void heapify(int[] arr, int index, int heapSize) {
    int left = (index << 1) + 1;
    while (left < heapSize) {
    int largest = left + 1 < heapSize && arr[left + 1] > arr[left] ? left + 1 : left;
    if (arr[index] >= arr[largest]) {
    break;
    }
    swap(arr, index, largest);
    index = largest;
    left = (index << 1) + 1;
    }
    }

    public boolean isFull() {
    return heapSize == limit;
    }

    public boolean isEmpty() {
    return heapSize == 0;
    }

    }

    /**
    * 交换数组两个元素的位置
    *
    * @param arr 数组
    * @param i 位置
    * @param j 位置
    */
    private static void swap(int[] arr, int i, int j) {
    // 同一个位置交换无意义,并且用异或交换会有问题
    if (i == j) {
    return;
    }
    // 交换
    arr[i] = arr[i] ^ arr[j];
    arr[j] = arr[i] ^ arr[j];
    arr[i] = arr[i] ^ arr[j];
    }

    }

    /* 如有错误,欢迎批评指正 */
  • 相关阅读:
    juniper ALARM亮红灯
    笔记本设置wifi热点
    基于apache+php+mysql 编译安装详解(转载)
    CentOS6.X 安装MySQL 5.X
    spring 多数据源切换
    Java Reflection(十二):动态类加载与重载
    Java Reflection(十一):动态代理
    Java Reflection(十):数组
    Java Reflection(九):泛型
    Java Reflection(八):注解
  • 原文地址:https://www.cnblogs.com/laydown/p/12815565.html
Copyright © 2011-2022 走看看