利用堆排序输出前n小的数 建堆 down操作
import java.util.*;
public class Main{
static int m;
static int n;
static int size;
static int[] h;
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
size = n;
h = new int[n + 1];
for(int i = 1; i <= n; i ++)h[i] = sc.nextInt();//注意下标从一开始
for(int i = n / 2; i >= 1; i --)down(i);//因为堆是一颗完全二叉树,len/2是最后一个非叶节点,只有最后一个非叶节点才有可能有左右孩子,才能进行down操作
while(m -- > 0){
System.out.print(h[1] + " ");
//因为数组直接删掉头节点后续操作比较麻烦,所以将尾节点赋值成头节点。
//删除size -- 既删除尾节点。最后头节点down即可
h[1] = h[size --];
down(1);
}
}
public static void down(int u){
int t = u;////t是为了找出u和u的左右子树中最小的节点
if(u * 2 <= size && h[t] > h[2 * u])t = u * 2;;//存在左儿子
if(u * 2 + 1 <= size && h[t] > h[2 * u + 1])t = u * 2 + 1;//存在右儿子
if(u != t){ //u不是最小位置位置需要下沉交换两值
int tmp = h[u];
h[u] = h[t];
h[t] = tmp;
down(t);
}
}
}up操作
public void up(int u){
while(u / 2 > 0 && h[u / 2] > h[u]){
int tmp = h[u / 2];
h[u / 2] = h[u];
h[u] = tmp;
u /= 2;
}
}
京公网安备 11010502036488号