堆排序算法模板:
// h存储堆中的值,h[1]是堆顶,h[x]的左儿子是2x,右儿子是2x+1
int[] h = new int[N];
// 向下调整
void down(int u) {
int t = u;
if (u * 2 <= size && h[u * 2] < h[t]) {
t = u * 2;
}
if (u * 2 + 1 <= size && h[u * 2 + 1] < h[t]) {
t = u * 2 + 1;
}
if (t != u) {
swap(t, u);
down(t);
}
}
// 向上调整
void up(int u) {
while (u / 2 > 0 && h[u / 2] > h[u]) {
swap(u / 2, u);
u /= 2;
}
}
// O(n) 建堆
for (int i = n / 2; i > 0; --i) {
down(i);
}
输入一个长度为 n 的整数数列,从小到大输出前 m 小的数。
输入格式
第一行包含整数 n 和 m。
第二行包含 n 个整数,表示整数数列
输出格式
共一行,包含 m 个整数,表示整数数列中前 m 小的数。
数据范围
- 1 ≤ m ≤ n ≤ 10^5
- 1 ≤ 数列中元素 ≤ 10^9
输入样例:
5 3
4 5 1 3 2
输出样例:
1 2 3
n, m = list(map(int, input().split(" ")))
h = [0] + list(map(int, input().split(" ")))
size = n
def down(u):
t = u
if u * 2 <= size and h[u * 2] < h[t]:
t = u * 2
if u * 2 + 1 <= size and h[u * 2 + 1] < h[t]:
t = u * 2 + 1
if t != u:
h[t], h[u] = h[u], h[t]
down(t)
def up(u):
while u // 2 > 0 and h[u // 2] > h[u]:
h[u // 2], h[u] = h[u], h[u // 2]
u //= 2
for i in range(n // 2, 0, -1):
down(i)
res = []
for i in range(m):
res.append(h[1])
h[1] = h[size]
size -= 1
down(1)
print(' '.join(list(map(str, res))))
import java.util.Scanner;
public class Main {
private static int[] h = new int[100010];
private static int size;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(), m = sc.nextInt();
for (int i = 1; i <= n; ++i) {
h[i] = sc.nextInt();
}
size = n;
for (int i = n / 2; i > 0; --i) {
down(i);
}
while (m-- > 0) {
System.out.print(h[1] + " ");
h[1] = h[size--];
down(1);
}
}
public static void down(int u) {
int t = u;
if (u * 2 <= size && h[u * 2] < h[t]) {
t = u * 2;
}
if (u * 2 + 1 <= size && h[u * 2 + 1] < h[t]) {
t = u * 2 + 1;
}
if (t != u) {
swap(t, u);
down(t);
}
}
public static void up(int u) {
while (u / 2 > 0 && h[u / 2] > h[u]) {
swap(u / 2, u);
u /= 2;
}
}
public static void swap(int i, int j) {
int t = h[i];
h[i] = h[j];
h[j] = t;
}
}
use std::io;
fn heap_sort(nums: &mut Vec<i32>) {
let n = nums.len();
for i in (0..n / 2).rev() {
sink(nums, i, n);
}
for i in (1..n).rev() {
let temp = nums[0];
nums[0] = nums[i];
nums[i] = temp;
sink(nums, 0, i);
}
}
fn sink(nums: &mut Vec<i32>, mut i: usize, n: usize) {
loop {
let left = i * 2 + 1;
let right = left + 1;
let mut largest = i;
if left < n && nums[left] > nums[largest] {
largest = left;
}
if right < n && nums[right] > nums[largest] {
largest = right;
}
if largest == i {
break;
}
let temp = nums[i];
nums[i] = nums[largest];
nums[largest] = temp;
i = largest;
}
}
fn main() -> io::Result<()> {
let mut s = String::new();
io::stdin().read_line(&mut s)?;
let s: Vec<usize> = s.split(' ').map(|s| s.trim().parse().unwrap()).collect();
// let n = s[0];
let m = s[1];
let mut nums = String::new();
io::stdin().read_line(&mut nums)?;
let mut nums: Vec<i32> = nums.split(' ').map(|s| s.trim().parse().unwrap()).collect();
heap_sort(&mut nums);
for num in nums.iter().take(m) {
print!("{} ", num);
}
Ok(())
}