题解 | #【模板】堆#
【模板】堆
https://www.nowcoder.com/practice/13f61c8c92404f5ea5d6fa4c692869fb
总结:
1.堆插入元素时,从下往上调整,由于相邻子树已经是大根堆,只需要不断与父节点比较大小,将大的节点和父节点互换,直到到达根节点或小于父节点即可结束。
2.堆删除元素时,为避免破坏ArrayList中堆的结构,可以将堆顶元素替换为最后一个元素,然后删除掉最后一个元素。堆删除元素后从上往下调整堆结构,将左右子节点中较大的节点与根节点互换,之后再递归调整该节点所在子树即可。由于堆结构未破坏,故其他结构不需要改变,节约了时间。
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n =Integer.parseInt(sc.nextLine());
MaxHeap maxHeap = new MaxHeap();
for(int i=0;i<n;i++){
String[] line = sc.nextLine().split(" ");
if(line[0].equals("push"))
maxHeap.push(Integer.parseInt(line[1]));
else if(line[0].equals("top"))
maxHeap.top();
else if(line[0].equals("pop"))
maxHeap.pop();
}
}
}
class MaxHeap{
private ArrayList<Integer> list = new ArrayList<>();
public MaxHeap(){
list.add(0);
}
public void push(int val){
list.add(val);
int len = list.size()-1;
while(list.get(len)>list.get(len/2)){
if(len==1)
break;
swap(len,len/2);
len = len/2;
}
}
public void top(){
int len = list.size()-1;
if(len==0)
System.out.println("empty");
else
System.out.println(list.get(1));
}
public void pop(){
int len = list.size()-1;
if(len==0)
System.out.println("empty");
else{
System.out.println(list.get(1));
list.set(1,list.get(len));
list.remove(len);
HeapAdjust(1,len-1);
}
}
public void HeapAdjust(int index,int len){
int left = index*2;
int maxIndex = 0;
while(left<=len){
if(left+1<=len)
maxIndex = list.get(left)>list.get(left+1)?left:left+1;
else
maxIndex=left;
if(list.get(index)>list.get(maxIndex))
break;
swap(index,maxIndex);
index = maxIndex;
left = 2*index;
}
}
public void swap(int l1,int l2){
int tmp = list.get(l1);
list.set(l1,list.get(l2));
list.set(l2,tmp);
}
}