AcWing 838. 【Java】堆排序 ( 从0开始 && 封装)
原题链接
简单
作者:
tt2767
,
2020-03-13 23:53:38
,
所有人可见
,
阅读 861
/**
1. 小根堆: 堆顶为最小元素, 每个节点都比它的左右儿子小
2. 需要2个函数调整:
2.1 pushUp: 当前元素较小, 向上调整
2.2 pushDown: 当前元素较大,向下调整
3. 支持操作:
3.1 add: data.append; pushUp(last);
3.2 peek: data.get(1)
3.3 pop: data.get(1); swap(1, last); pushDown(1); data.pop;
3.3 update: data.put(index, value); value > oldValue ? pushDown(index) : pushUp(index);
3.4 remove: update(index, data.get(last)); data.pop;
*/
import java.util.*;
import java.util.stream.*;
class Main{
class Heap{
List<Integer> data;
public Heap(int[] arr){
data = new ArrayList<>();
for (int i = 0 ; arr != null && i < arr.length ; i++) data.add(arr[i]);
for (int i = (data.size() >> 1) - 1 ; i >= 0; i--) pushDown(i);
}
private int last(int index){
if (left(index) >= data.size() && right(index) >= data.size()) return data.size();
if (left(index) >= data.size()) return right(index);
if (right(index) >= data.size()) return left(index);
return data.get(left(index)) < data.get(right(index)) ? left(index) : right(index);
}
private int father(int index) {return (index-1) >> 1;}
private int left(int index) {return index << 1 | 1;}
private int right(int index) {return (index << 1) + 2 ;}
private void pushUp(int index){
for (int f = father(index);0 <= f && 0 < index && data.get(index) < data.get(f) ; f=father(index = f))
Collections.swap(data, f, index);
}
private void pushDown(int index){
for (int child = last(index); child < data.size() && data.get(child) < data.get(index); child=last(index = child))
Collections.swap(data, child, index);
}
public void add(int value){
data.add(value);
pushUp(data.size()-1);
}
public int peek(){ return data.get(0);}
public int pop(){return delete(0);}
public int update(int index, int value){
int old = data.get(index);
data.set(index, value);
pushDown(index);
pushUp(index);
return old;
}
public int delete(int index){
int value = data.get(data.size()-1);
data.remove(data.size()-1);
return data.isEmpty() ? value : update(index, value);
}
}
void run(){
int n = jin.nextInt();
int m = jin.nextInt();
// Heap heap = new Heap();
// for (int i = 0 ; i < n ; i ++) {
// heap.add(jin.nextInt());
// }
int[] data = new int[n];
for (int i = 0 ; i < n ; i ++) data[i] = jin.nextInt();
Heap heap = new Heap(data);
List<Integer> list = new ArrayList<>();
for (int i = 0 ; i < m ; i ++ ) list.add(heap.pop());
String res = list.stream().map(String::valueOf).collect(Collectors.joining(" "));
System.out.println(res);
}
private Scanner jin = new Scanner(System.in);
public static void main(String[] args) {new Main().run();}
}