TOP K问题:利用堆排序找出数组中最小的k个数

ops/2024/12/30 22:19:27/

设计一个算法,找出数组中最小的k个数。以任意顺序返回这k个数均可。

找小的数需要建大堆来解决,首先将数组中前K个数建成一个大堆,将从k+1个数直到数组结束的所有数与堆顶的数进行比较,如果比堆顶的数小,则替换堆顶的数据,然后在向下调整,重新形成一个新的大堆,如果比堆顶的数小,则不替换。以此循环,直至数组k+1个数到数组结束所有的数都比较完,最后留在堆里的数就是最小的k个数。用题中的题目来说:使用前4个数 1 3 5 7 来建一个大堆。

替换了之后由于不是一个大堆,所以进行向下调整,形成一个新的大堆。

替换了之后进行向下调整

最后输出的结果

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>

void AdjustDown(int* a, int n, int root)//向下调整
{
    int parent = root;
    int child = parent * 2 + 1;
    while (child < n)
    {
        if (child + 1 < n && a[child + 1] > a[child])//选出大的那个孩子
        {
            child++;
        }
        if (a[child] > a[parent])
        {
            int tmp = a[child];
            a[child] = a[parent];
            a[parent] = tmp;
            parent = child;
            child = parent * 2 + 1;
        }
        else
        {
            break;
        }
    }
}

int* smallestK(int* arr, int arrSize, int k, int* returnSize)
{
    *returnSize = k;
    if (k == 0)
        return NULL;
    int* retArr = (int*)malloc(sizeof(int) * k);
    int i = 0;
    for (i = 0; i < k; i++)
    {
        retArr[i] = arr[i];
    }
    //建K个数的大堆
    for (i = (k - 1 - 1) / 2; i >= 0; i--)
    {
        AdjustDown(retArr, k, i);
    }

    for (i = k; i < arrSize; i++)
    {
        if (arr[i] < retArr[0])
        {
            retArr[0] = arr[i];
            AdjustDown(retArr, k, 0);
        }
    }
    *returnSize = k;

    return retArr;
}

int main()
{
    // 测试数据
    int arr[] = { 1,3,5,7,2,4,6,8 };
    int arrSize = sizeof(arr) / sizeof(arr[0]);
    int k = 4;
    int returnSize;

    // 调用 smallestK 函数
    int* result = smallestK(arr, arrSize, k, &returnSize);

    // 输出结果
    printf("The smallest %d elements are:\n", k);
    for (int i = 0; i < returnSize; i++) {
        printf("%d ", result[i]);
    }
    printf("\n");

    // 释放分配的内存
    free(result);
    return 0;
}


http://www.ppmy.cn/ops/145917.html

相关文章

Fuzzing技术总结

Fuzzing技术总结&#xff08;Brief Surveys on Fuzz Testing&#xff09; PrologueIntroductionRecent Related WorkOpen Source ToolsUseful Blog Article Prologue 这里另一篇文章总结了最近与Fuzzing相关的论文&#xff1a; https://github.com/wcventure/FuzzingPaper …

使用GitHub Pages部署静态网站:简易指南

文章目录 前言一、什么是GitHub Pages&#xff1f;二、准备工作三、创建GitHub仓库四、构建静态网站内容五、部署到GitHub Pages六、自定义设置结语 前言 随着互联网的发展&#xff0c;个人开发者和小型团队对于快速创建和发布网站的需求日益增长。在众多的解决方案中&#xf…

短视频矩阵系统源码开发之账号管理技术深度剖析,支持OEM

一、引言 在短视频矩阵系统中&#xff0c;账号管理技术是核心模块之一&#xff0c;它承担着确保多平台账号安全、高效运营以及数据整合的重要职责。一个健壮、灵活且安全的账号管理系统&#xff0c;能够为用户提供便捷的账号操作体验&#xff0c;同时也为整个短视频矩阵的稳定运…

《PHP MySQL 插入数据》

《PHP MySQL 插入数据》 介绍 PHP是一种广泛使用的服务器端脚本语言&#xff0c;而MySQL是一种流行的关系型数据库管理系统。在Web开发中&#xff0c;经常需要将用户输入的数据存储到数据库中。本文将详细介绍如何使用PHP和MySQL实现数据的插入操作。 环境准备 在开始之前&…

docker基础命令入门、镜像、运行容器、操作容器

一. Docker 基础入门相关命令 1.1 启动Docker 1.2 查看 Docker 运行状态 1.3 停止 Dokcer 1.4 重启Docker 1.5 配置开机启动 docker 1.6 查看 docker 所有命令 二. Docker 镜像相关命令 2.1 docker search 镜像名称——(查询某个镜像) 2.2 docker pull 镜像名称:version…

多技术栈时代的利器:自动化协作流水线全面实践

文章目录 Jenkins的自动化流水线优势设计自动化流水线架构使用 Jenkinsfile 实现流水线声明流水线和工具拉取代码构建与测试容器化部署到 Kubernetes后续处理 QA 环节未来的扩展方向总结 Jenkins的自动化流水线优势 Jenkins 是一款备受开发者推崇的开源自动化服务器&#xff0…

视频字幕生成工具(类似 MemoAI)简介

视频字幕生成工具,像你提到的那样,利用 机器学习 和 自然语言处理 技术来为视频内容自动生成字幕,并支持多种语言的翻译。这些工具在很多领域中非常有用,尤其是在教育、媒体制作、内容创作和跨语言交流中。 主要功能: 语音识别(ASR): 自动转录:工具首先会识别视频中的…

STM32 + 移远EC800 4G通信模块数传

一、4G模块简述 EC800M-CN 是移远通信&#xff08;Quectel&#xff09;推出的一款高性能、超小尺寸的 LTE Cat 1 无线通信模块&#xff0c;专为 M2M&#xff08;机器对机器&#xff09;和 IoT&#xff08;物联网&#xff09;应用设计。它具有以下主要特点&#xff1a; 通信速率…