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];
    }

    }

    /* 如有错误,欢迎批评指正 */
  • 相关阅读:
    洛谷P3258 [JLOI2014]松鼠的新家
    洛谷P1306 斐波那契公约数
    bzoj4247:挂饰
    [YTU]_2354 (H 实现复数类中的加运算符重载【C++运算符重载】)
    [YTU]_2440 (C++习题 复数类--重载运算符+,-,*,/)
    [YTu]_2441 (C++习题 复数类--重载运算符2+)
    [YTu]_2439(C++习题 复数类--重载运算符+)
    10.3 重载双目运算符
    10.2.1 关于vc++不支持把类的成员函数定义为类的友元函数的处理
    10.2 运算符重载函数作为类成员函数和友元函数
  • 原文地址:https://www.cnblogs.com/laydown/p/12815565.html
Copyright © 2011-2022 走看看