当前位置:网站首页>系统提供的堆 VS 手动改写堆
系统提供的堆 VS 手动改写堆
2022-08-09 12:01:00 【爱敲代码的Harrison】
要求:在一个已经组织好的大根堆或者小根堆中,更改其中的某个值后,仍要求其为大根堆或者小根堆
为啥系统提供的堆实现不了,因为系统提供的堆结构不会记indexMap这张反向表。但是如果系统增加了这张反向表,实现代价又会很高,而且系统也不确定你会不会用到这些功能,所以系统干脆不提供了,大量的情况就是这样。但是不排除某种语言中有这个功能(也就是有resign()这个方法),但是C++跟Java中是没有的,所以这种情况下需要自己手动改写堆结构!
具体请看下面代码和运行结果吧!
package com.harrison.class04;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.PriorityQueue;
public class Code06_HeapGreater {
public static class MyHeap<T>{
private ArrayList<T> heap;
// 为啥系统实现不了,自己手动改写后能实现,关键在于indexMap表
// 任何一个你给我的样本T,记录着它在堆heap上的什么位置Integer
private HashMap<T, Integer> indexMap;
private int heapSize;
// 告诉我关于样本类型T的比较器comparator
// 有了这个比较器就知道如何比较大小了
private Comparator<? super T> comparator;
public MyHeap(Comparator<? super T> com) {
heap=new ArrayList<>();
indexMap=new HashMap<>();
heapSize=0;
comparator=com;
}
public boolean isEmpty() {
return heapSize==0;
}
public int size() {
return heapSize;
}
public boolean contains(T key) {
return indexMap.containsKey(key);
}
public void push(T value) {
heap.add(value);
indexMap.put(value, heapSize);
heapInsert(heapSize++);
}
public void heapInsert(int index) {
// 比较器告诉你 你自己跟父结点如何比较大小
while(comparator.compare(heap.get(index), heap.get((index-1)/2))<0){
swap(index, (index-1)/2);
index=(index-1)/2;
}
}
public T pop() {
T ans=heap.get(0);
int end=heapSize-1;
swap(0, end);
// 移除的是堆中的位置!!不是样本!!!
heap.remove(end);
indexMap.remove(ans);
heapify(0, --heapSize);
return ans;
}
public void heapify(int index,int heapSize) {
int left=index*2+1;
while(left<heapSize) {
int largest=(left+1<heapSize &&
comparator.compare(heap.get(left+1), heap.get(left))<0
)?left+1:left;
int allLargest=comparator.compare(heap.get(largest), heap.get(index))<0
?largest:index;
if(allLargest==index) {
break;
}
swap(allLargest, index);
index=allLargest;
left=2*index+1;
}
}
// 关键方法:为什么在一个大根堆或者小根堆中更改某个值后,仍然能调整为大根堆或小根堆
// 用户要求改变堆中的某个值,但是没告诉我们这个值应该是往上移动还是往下移动
// 通过indexMap表找到样本在堆中的哪个位置,然后调整为大根堆或小根堆
public void resign(T value) {
int valueIndex=indexMap.get(value);
// 两个方法只会中一个
heapInsert(valueIndex);
heapify(valueIndex, heapSize);
}
// 在堆和indexMap表中交换i位置和j位置的数
// heap有任何变换,indexMap表都要跟着一起变,保证两个结构强同步
public 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);
}
}
public static class Student{
public int classNo;
public int age;
public int id;
public Student(int c,int a,int i) {
classNo=c;
age=a;
id=i;
}
}
public static class StudentComparator implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
// TODO Auto-generated method stub
return o1.age-o2.age;
}
}
public static void main(String[] args) {
System.out.println("系统提供的堆:");
Student s1=null;
Student s2=null;
Student s3=null;
Student s4=null;
Student s5=null;
Student s6=null;
s1=new Student(2, 50, 11111);
s2=new Student(1, 60, 22222);
s3=new Student(6, 10, 33333);
s4=new Student(3, 20, 44444);
s5=new Student(7, 72, 55555);
s6=new Student(1, 14, 66666);
PriorityQueue<Student> heap=new PriorityQueue<>(new StudentComparator());
heap.add(s1);
heap.add(s2);
heap.add(s3);
heap.add(s4);
heap.add(s5);
heap.add(s6);
while(!heap.isEmpty()) {
Student cur=heap.poll();
System.out.println(cur.classNo+","+cur.age+","+cur.id);
}
System.out.println("======================");
System.out.println("手动改写的堆:");
MyHeap<Student> myHeap=new MyHeap<>(new StudentComparator());
myHeap.push(s1);
myHeap.push(s2);
myHeap.push(s3);
myHeap.push(s4);
myHeap.push(s5);
myHeap.push(s6);
while(!myHeap.isEmpty()) {
Student cur=myHeap.pop();
System.out.println(cur.classNo+","+cur.age+","+cur.id);
}
System.out.println("======================");
System.out.println("系统提供的堆(改了堆中某些值):");
s1=new Student(2, 50, 11111);
s2=new Student(1, 60, 22222);
s3=new Student(6, 10, 33333);
s4=new Student(3, 20, 44444);
s5=new Student(7, 72, 55555);
s6=new Student(1, 14, 66666);
heap=new PriorityQueue<>(new StudentComparator());
heap.add(s1);
heap.add(s2);
heap.add(s3);
heap.add(s4);
heap.add(s5);
heap.add(s6);
s2.age=6;
s4.age=12;
s5.age=10;
s6.age=84;
while(!heap.isEmpty()) {
Student cur=heap.poll();
System.out.println(cur.classNo+","+cur.age+","+cur.id);
}
System.out.println("======================");
System.out.println("手动改写的堆(改了堆中某些值):");
s1=new Student(2, 50, 11111);
s2=new Student(1, 60, 22222);
s3=new Student(6, 10, 33333);
s4=new Student(3, 20, 44444);
s5=new Student(7, 72, 55555);
s6=new Student(1, 14, 66666);
myHeap=new MyHeap<>(new StudentComparator());
myHeap.push(s1);
myHeap.push(s2);
myHeap.push(s3);
myHeap.push(s4);
myHeap.push(s5);
myHeap.push(s6);
s2.age=6;
myHeap.resign(s2);
s4.age=12;
myHeap.resign(s4);
s5.age=10;
myHeap.resign(s5);
s6.age=84;
myHeap.resign(s6);
while(!myHeap.isEmpty()) {
Student cur=myHeap.pop();
System.out.println(cur.classNo+","+cur.age+","+cur.id);
}
}
}
边栏推荐
- 智驾科技完成C1轮融资,此前2轮已融4.5亿元
- Scala 高阶(七):集合内容汇总(上篇)
- 8、IDEA提交代码出现: Fetch failed fatal: Could not read from remote repository
- How to upload local file trial version in binary mode in ABAP report
- WPF implements a MessageBox message prompt box with a mask
- 虚拟机安装出现的问题汇总
- 太卷了... 腾讯一面被问到内存满了,会发生什么?
- 2022 Niu Ke Duo School (6) M. Z-Game on grid
- Recommend a free 50-hour AI computing platform
- 实验记录:搭建网络过程
猜你喜欢
非科班AI小哥火了:他没有ML学位,却拿到DeepMind的offer
腾讯欲成育碧最大股东/ 米哈游招NLP内容生成研究员/ AI发现四千余物种濒临灭绝...今日更多新鲜事在此...
GRPC整体学习
shell脚本------函数的格式,传参,变量,递归,数组
放下手机吧:实验表明花20分钟思考和上网冲浪同样快乐
Shell之常用小工具(sort、uniq、tr、cut)
基于CAP组件实现补偿事务与幂等性保障
JD.com architects tidy up: what are the core technical knowledge points of jvm and performance tuning
虚拟机安装出现的问题汇总
专业人士使用的 11 种渗透测试工具
随机推荐
正则表达式(规则,匹配,和实际使用)
箭头函数和普通函数的常见区别
AQS Synchronization Component - FutureTask Analysis and Use Cases
水能自发变成“消毒水”,83岁斯坦福教授:揭示冬天容易得流感的部分原因...
又有大厂员工连续加班倒下/ 百度搜狗取消快照/ 马斯克生父不为他骄傲...今日更多新鲜事在此...
报告:想学AI的学生数量已涨200%,老师都不够用了
字节秋招二面把我干懵了,问我SYN报文什么情况下会被丢弃?
ThreadLocal的简单理解
从零开始Blazor Server(9)--修改Layout
8、IDEA提交代码出现: Fetch failed fatal: Could not read from remote repository
从零开始Blazor Server(9)--修改Layout
OpenSSF的开源软件风险评估工具:Scorecards
h264 protocol
微服务架构的核心关键点
Blazor Server (9) from scratch -- modify Layout
在北极都可以穿短袖了,温度飙升至32.5℃
曼城推出可检测情绪的智能围巾,把球迷给整迷惑了
Blocking, non-blocking, multiplexing, synchronous, asynchronous, BIO, NIO, AIO all in one pot
JS 封装节流(后期优化)
web课程设计