利用堆排序输出前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; } }