Acwing838堆排序

思路

如何手写一个堆,在这主要应用数组去实现一个堆。

  1. 插入一个数 heap[++ size] = x; up(size);
  2. 求集合当中的最小值 heap[1]
  3. 删除最小值 heap[1] = heap[size];size--;down(1);
  4. 删除任意一个元素 heap[k] = heap[size];size--;up(k);down(k);
  5. 修改任意一个元素 heap[k] = x;down(k);up(k);

题目

输入一个长度为 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

代码

java 复制代码
import java.util.Scanner;

public class Main {

    static int cnt, n, m, N = 100010;
    static int[] a = new int[N];

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        n = in.nextInt(); // 输入数组的大小
        m = in.nextInt(); // 操作次数
        for (int i = 1; i <= n; i++) {
            a[i] = in.nextInt(); // 输入数组元素
        }
        cnt = n; // 堆中元素个数初始化为n
        // 建堆过程
        for (int i = n / 2; i >= 1; i--) {
            down(i); // 对每个非叶子节点进行下沉操作,构建小顶堆
        }
        // 执行m次操作
        while (m > 0) {
            m--;
            System.out.print(a[1] + " "); // 输出堆顶元素(最小值)
            a[1] = a[cnt--]; // 将堆顶元素替换为堆尾元素,堆元素个数减1
            down(1); // 对新的堆顶元素进行下沉操作,维护小顶堆性质
        }
    }

    // 下沉操作,将节点u下沉到合适的位置,以维护小顶堆性质
    private static void down(int u) {
        int t = u; // 记录最小值的位置
        // 如果存在左子节点,且左子节点的值小于当前节点值,则更新最小值位置
        if (u * 2 <= cnt && a[u * 2] < a[t]) t = u * 2;
        // 如果存在右子节点,且右子节点的值小于当前节点值,则更新最小值位置
        if (u * 2 + 
相关推荐
IT_陈寒7 小时前
Python多进程共享变量那个坑,我差点没爬出来
前端·人工智能·后端
码事漫谈7 小时前
2026软考高级·系统架构设计师备考指南
后端
AI茶水间管理员9 小时前
如何让LLM稳定输出 JSON 格式结果?
前端·人工智能·后端
其实是白羊9 小时前
我用 Vibe Coding 搓了一个 IDEA 插件,复制URI 再也不用手动拼了
后端·intellij idea
用户8356290780519 小时前
Python 操作 Word 文档节与页面设置
后端·python
酒後少女的夢10 小时前
设计模式教程
后端·架构
凌览10 小时前
别再手搓 Skill 了,用这个工具 5 分钟搞定
前端·后端
weixin_4080996710 小时前
python请求文字识别ocr api
开发语言·人工智能·后端·python·ocr·api·ocr文字识别
weixin_4080996710 小时前
【组合实战】OCR + 图片去水印 API:自动清洗图片再识别文字(完整方案 + 代码示例)
图像处理·后端·ocr·api·文字识别·去水印·ocr识别优化