思路(详细的看代码就好)
代码
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 100010;
int h[N], mySize;
int n, m;
void down(int u)//u是根节点 t是最小节点
{
int t = u;
if (2 * u <= mySize && h[t] > h[2 * u]) //左节点存在 求左节点
t = 2 * u;
if (2 * u + 1 <= mySize && h[t] > h[2 * u + 1])//右节点存在 求右节点
t = 2 * u + 1;
if (u != t)//如果最小节点不是根节点 交换最小节点和根节点 确保小根堆
{
swap(h[u], h[t]);
down(t);//递归实现小根堆
}
}
int main()
{
cin >> n >> m;
mySize = n;
for (int i = 1; i <= n; i++)
scanf("%d", &h[i]);
for (int i = n / 2; i; i--)
down(i);
while (m--)
{
cout << h[1] << " ";//最小值一定是根节点对应的数
h[1] = h[mySize--];//每次输出根节点后 要用最后一个节点补上根节点空位置
down(1);//然后重新调整整个队
}
return 0;
}