• 最大堆



    /**
    * 堆通常是一个可以被看做一棵树的数组对象。
    * 堆总是满足下列性质:
    * 堆中某个节点的值总是不大于或不小于其父节点的值;
    * 堆总是一棵完全二叉树。
    * 将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆
    */
    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];
    }

    }

    /* 如有错误,欢迎批评指正 */
  • 相关阅读:
    列表、元组、字典、集合类型及其内置方法
    Python数字类型及字符串类型的内置方法 ##
    Python之流程控制
    前端混合
    数据库
    oracle 11g 安装过程
    SQLAlchemy
    pipreqs快速生成python项目所需的依赖
    llinux基本操作
    linux简介
  • 原文地址:https://www.cnblogs.com/laydown/p/12815565.html
Copyright © 2020-2023  润新知