【算法&数据结构体系篇class07】:加强堆

文章介绍了如何通过建立反向索引表和自定义比较器来增强系统堆的功能,以支持更高效的操作,如O(logN)时间内的元素调整和删除。此外,文章提供了一个具体的Java实现示例,用于解决用户颁奖问题,该问题涉及根据购买行为动态维护得奖名单,确保性能高效且符合特定规则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、手动改写堆(非常重要)!

系统提供的堆无法做到的事情:
1)已经入堆的元素,如果参与排序的指标方法变化
系统提供的堆无法做到时间复杂度O(logN)调整!都是O(N)的调整!
2)系统提供的堆只能弹出堆顶做不到自由删除任何一个堆中的元素,
或者说,无法在时间复杂度O(logN)内完成!一定会高于O(logN)
根本原因:无反向索引表

二、加强堆的核心点

1)建立反向索引表indexMap

2)建立比较器

3)核心在于各种结构相互配合,非常容易出错

三、构建加强堆演示

package class07;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;

/**
 * 手写一个加强堆,比系统自带的优先队列多了更多高效的获取元素查询动作
 * 注意泛型:T一定要是非基础类型,有基础类型需求包一层
 */
public class HeapGreaterTrain<T> {
    //保存堆元素的集合
    public ArrayList<T> heap;
    //保存堆元素对应的索引位置 元素:索引
    public HashMap<T, Integer> indexMap;
    //堆大小
    public int heapSize;
    //比较器,自定义的比较器 ?匹配类型是T的父类 包括T本身
    public Comparator<? super T> comp;

    public HeapGreaterTrain(Comparator<? super T> c) {
        heap = new ArrayList<>();
        indexMap = new HashMap<T, Integer>();
        heapSize = 0;
        comp = c;
    }

    //判断堆是否为空
    public boolean isEmpty() {
        return heapSize == 0;
    }

    //判断堆大小
    public int size() {
        return heapSize;
    }

    //判断堆中是否包含某个元素
    public boolean contains(T obj) {
        return indexMap.containsKey(obj);
    }

    //查询堆顶元素
    public T peek() {
        return heap.get(0);
    }

    //入堆操作
    public void push(T obj) {
        //直接进集合最后,反向索引表创建关系,后面再接着insert向上排序
        heap.add(obj);
        indexMap.put(obj, heapSize);
        heapInsert(heapSize++);
    }

    //堆向上交换操作,默认是小根堆的排序
    private void heapInsert(int i) {
        //通过业务创建加强堆自定义的比较器来定义排序,假设返回小于0,执行交换操作
        while (comp.compare(heap.get(i), heap.get((i - 1) / 2)) < 0) {
            swap(i, (i - 1) / 2);
            i = (i - 1) / 2;
        }
    }

    //出堆操作
    public T pop(){
        //出堆顶,然后与最后一个元素交换,再将最后一个元素从集合与反向索引表删除
        T ans = heap.get(0);
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值