左神算法:加强堆的实现(Java) 小鱼儿 2022-09-06 00:18 128阅读 0赞 ## 为什么要有加强堆? ## Java中的PriorityQueue(优先级队列)就是系统提供的堆实现,那么为什么还要手动去实现? 假如现在你手里有一个堆,里面存着一些元素,用户此时说要改变元素的排序指标且要求高效,怎么办?用系统实现的堆,你是不是只能把堆中的元素拿出来再重新去调整。 此时你的用户又想删除堆中的某一个元素,你要怎么删除指定元素又能保证堆结构呢?系统提供的堆是不是无能为力,或者说系统提供的堆不能高效的满足你的需求,你只能去手动改写。 这里我们想一想:系统的堆为什么不能满足我们的需求,根本原因在于:元素进堆之后,我们不能确定元素在堆的位置,如果我们能知道堆中元素的位置,不管调整还是删除元素,是不是只需要在它的当前位置进行heapInsert或者heapify操作就可以了。 这就是加强堆的作用,给堆中的元素增加一张反向索引表,记录入堆元素的位置,用来满足我们的需求。具体代码如下: ## 代码 ## [腾讯课堂][Link 1] package class04_07; import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; import java.util.List; /* * T一定要是非基础类型,有基础类型需求包一层 */ public class HeapGreater<T> { private ArrayList<T> heap; private HashMap<T, Integer> indexMap; private int heapSize; private Comparator<? super T> comp; public HeapGreater(Comparator<T> c) { heap = new ArrayList<>(); indexMap = new HashMap<>(); 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) { heap.add(obj); indexMap.put(obj, heapSize); heapInsert(heapSize++); } public T pop() { T ans = heap.get(0); swap(0, heapSize - 1); indexMap.remove(ans); heap.remove(--heapSize); heapify(0); return ans; } public void remove(T obj) { T replace = heap.get(heapSize - 1); int index = indexMap.get(obj); indexMap.remove(obj); heap.remove(--heapSize); if (obj != replace) { heap.set(index, replace); indexMap.put(replace, index); resign(replace); } } public void resign(T obj) { heapInsert(indexMap.get(obj)); heapify(indexMap.get(obj)); } // 请返回堆上的所有元素 public List<T> getAllElements() { List<T> ans = new ArrayList<>(); for (T c : heap) { ans.add(c); } return ans; } private void heapInsert(int index) { while (comp.compare(heap.get(index), heap.get((index - 1) / 2)) < 0) { swap(index, (index - 1) / 2); index = (index - 1) / 2; } } private void heapify(int index) { int left = index * 2 + 1; while (left < heapSize) { int best = left + 1 < heapSize && comp.compare(heap.get(left + 1), heap.get(left)) < 0 ? (left + 1) : left; best = comp.compare(heap.get(best), heap.get(index)) < 0 ? best : index; if (best == index) { break; } swap(best, index); index = best; left = index * 2 + 1; } } private void swap(int i, int j) { T o1 = heap.get(i); T o2 = heap.get(j); heap.set(i, o2); heap.set(j, o1); indexMap.put(o2, i); indexMap.put(o1, j); } } [Link 1]: https://ke.qq.com/webcourse/3067253/103187834#taid=10471980674239861&vid=5285890810611674308
相关 python算法口诀_左神算法初级4 python实现 初级4的题目相关代码: 1、转圈打印矩阵 \转圈打印矩阵(二维数组), 比如a矩阵 \ \[\[ 1 2 3\] \ \[ 4 5 6\] \ \[ 7 8 9\] 桃扇骨/ 2022年11月05日 13:51/ 0 赞/ 90 阅读
相关 左神算法进阶班3_4网易题——烽火传递 【题目】 一个数组中的数字组成环形山,数值为山高 1 2 4 5 3 规则,烽火传递: 相邻之间的两座山必能看到烽火, 非相邻的山之间有一边的山高都 <= Bertha 。/ 2022年10月02日 15:55/ 0 赞/ 117 阅读
相关 左神算法进阶班3_1构造数组的MaxTree 题目 一个数组的MaxTree定义: 数组必须没有重复元素 MaxTree是一棵二叉树,数组的每一个值对应一个二叉树节点 包括MaxTree树在内且在 缺乏、安全感/ 2022年10月02日 15:55/ 0 赞/ 87 阅读
相关 左神算法:加强堆的实现(Java) 为什么要有加强堆? Java中的PriorityQueue(优先级队列)就是系统提供的堆实现,那么为什么还要手动去实现? 假如现在你手里有一个堆,里面存着一些元素,用户 小鱼儿/ 2022年09月06日 00:18/ 0 赞/ 129 阅读
相关 java实现左式堆 任一节点X的零路径长(null path length)npl(X)定义为到从X到一个不具有两个儿子的节点的最短路径的长。 不具有两个儿子的节点即是叶子节点和单孩子节点。 落日映苍穹つ/ 2022年06月08日 14:05/ 0 赞/ 137 阅读
相关 【搞定左神算法初级班】第6节:前缀树、贪心算法 目 录: 一、前缀树:Prefix Tree 1.1 前缀树题目举例:一个字符串类型的数组 arr1,另一个字符串类型的数组 arr2 1.2 前缀树的 insert 以你之姓@/ 2022年02月26日 13:20/ 0 赞/ 182 阅读
相关 左神算法进阶班1_4Manacher算法 1 include <iostream> 2 include <string> 3 4 using namespace std; 朴灿烈づ我的快乐病毒、/ 2022年01月06日 00:01/ 0 赞/ 162 阅读
相关 左神算法进阶班3_2求最大矩阵 【题目】 给定一个整型矩阵map,其中的值只有0和1两种,求其中全是1 的所有矩形区域中,最大的矩形区域为1的数量。 例如: 1 1 1 0 逃离我推掉我的手/ 2022年01月05日 23:55/ 0 赞/ 132 阅读
相关 【左神算法】一种接收消息并按顺序打印的结构设计 > 题目:一种消息接收并打印的结构设计:已知一个消息流会不断地吐出整数 1 ~ N,但不一定按照顺序吐出。如果上次打印的数为i,那么当 i + 1 出现时,请打印 i + 1 妖狐艹你老母/ 2021年11月27日 05:40/ 0 赞/ 251 阅读
还没有评论,来说两句吧...