数据结构-最大堆使用教程

本文介绍了如何在Java中通过自定义Comparator实现PriorityQueue的最大堆,以及如何手动创建一个最大堆类,包括添加元素、提取最大元素和维护堆性质的方法。
摘要由CSDN通过智能技术生成

在Java中,可以通过实现自己的最大堆数据结构或修改现有的PriorityQueue来实现最大堆。Java的PriorityQueue类是基于优先级堆实现的,其默认行为是最小堆。为了使其表现为最大堆,我们可以提供一个自定义比较器来逆转排序顺序。

以下是使用Java内置PriorityQueue实现最大堆的示例:

import java.util.Comparator;
import java.util.PriorityQueue;

public class MaxHeapExample {
    public static void main(String[] args) {
        // 使用自定义比较器实现最大堆
        PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Comparator.reverseOrder());

        // 添加元素到堆
        maxHeap.offer(3);
        maxHeap.offer(1);
        maxHeap.offer(4);
        maxHeap.offer(1);
        maxHeap.offer(5);
        maxHeap.offer(9);
        maxHeap.offer(2);
        maxHeap.offer(6);
        maxHeap.offer(5);
        maxHeap.offer(3);

        // 提取最大元素(堆顶元素)
        System.out.println("Max Value: " + maxHeap.poll()); // 输出 9

        // 继续提取最大元素
        while (!maxHeap.isEmpty()) {
            System.out.println(maxHeap.poll());
        }
    }
}

如果你想手动实现一个最大堆,你可以创建一个类,其中包含一个数组以及方法来维护堆的性质(如添加元素、提取最大元素等)。以下是一个手动实现的最大堆的简单示例:

public class MaxHeap {
    private int[] heap;
    private int size;
    private int maxSize;

    public MaxHeap(int maxSize) {
        this.maxSize = maxSize;
        this.size = 0;
        heap = new int[this.maxSize];
    }

    private int parent(int pos) {
        return (pos - 1) / 2;
    }

    private int leftChild(int pos) {
        return (2 * pos) + 1;
    }

    private int rightChild(int pos) {
        return (2 * pos) + 2;
    }

    private void swap(int fpos, int spos) {
        int tmp = heap[fpos];
        heap[fpos] = heap[spos];
        heap[spos] = tmp;
    }

    private void maxHeapify(int pos) {
        if (!isLeaf(pos)) {
            if (heap[pos] < heap[leftChild(pos)] || heap[pos] < heap[rightChild(pos)]) {
                if (heap[leftChild(pos)] > heap[rightChild(pos)]) {
                    swap(pos, leftChild(pos));
                    maxHeapify(leftChild(pos));
                } else {
                    swap(pos, rightChild(pos));
                    maxHeapify(rightChild(pos));
                }
            }
        }
    }

    private boolean isLeaf(int pos) {
        return pos >= (size / 2) && pos < size;
    }

    public void insert(int element) {
        if (size >= maxSize) {
            return;
        }

        heap[size] = element;
        int current = size;
        size++;

        while (heap[current] > heap[parent(current)]) {
            swap(current, parent(current));
            current = parent(current);
        }
    }

    public int extractMax() {
        if (size == 0) {
            throw new IllegalStateException("Heap is empty");
        }

        int popped = heap[0];
        heap[0] = heap[--size];
        maxHeapify(0);
        return popped;
    }

    // 调用示例
    public static void main(String[] args) {
        MaxHeap maxHeap = new MaxHeap(10);
        maxHeap.insert(3);
        maxHeap.insert(1);
        maxHeap.insert(4);
        maxHeap.insert(1);
        maxHeap.insert(5);
        maxHeap.insert(9);
        maxHeap.insert(2);
        maxHeap.insert(6);
        maxHeap.insert(5);
        maxHeap.insert(3);

        // 提取最大元素(堆顶元素)
        System.out.println("Max Value: " + maxHeap.extractMax()); // 输出 9

        // 继续提取最大元素
        while (maxHeap.size > 0) {
            System.out.println(maxHeap.extractMax());
        }
    }
}

在这个手动实现的最大堆中,我们使用数组来存储堆结构。insert() 方法用于添加新元素到堆中,它会从堆的底部开始,并确保堆的性质通过与父节点比较并在必要时交换位置。extractMax() 方法用于提取并删除堆中的最大元素,即数组的第一个元素,并重新调整堆的结构以保持最大堆的性质。maxHeapify() 是一个重要的辅助方法,它用于在提取元素后重新整理堆的结构。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员爱学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值