Acwing---838. 堆排序

2024-02-11 14:52
文章标签 堆排序 acwing 838

本文主要是介绍Acwing---838. 堆排序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

堆排序

  • 1.题目
  • 2.基本思想
  • 3.代码实现

1.题目

输入一个长度为 n的整数数列,从小到大输出前 m 小的数。

输入格式
输入一个长度为 n 的整数数列,从小到大输出前 m 小的数。

输出格式
共一行,包含 m 个整数,表示整数数列中前 m 小的数。

数据范围
1 ≤ m ≤ n ≤ 1 0 5 , 1≤m≤n≤10^5, 1mn105

1 ≤ 数列中元素 ≤ 1 0 9 1≤数列中元素≤10^9 1数列中元素109

输入样例:

5 3
4 5 1 3 2

输出样例:

1 2 3

2.基本思想

  • 如何手写一个堆?完全二叉树 5个操作
  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; up(k); down(k);

3.代码实现

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;public class Main {static int N = 100010;static int[] h = new int[N];static int size;public static void main(String[] args) throws IOException {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;//初始化size,表示堆里有n 个元素for (int i = n / 2; i > 0; i--) down(i);//把堆初始化成小根堆,从二叉树的倒数第二行开始,把数字大的下沉while (m-- > 0) {System.out.print(h[1] + " ");//小顶堆 最小就是第一个h[1] = h[size];//末尾元素上移size--;down(1);}}private static void down(int u) {int min = u;//存储三个结点中存在的最小的结点的下标,初始化为当前结点minif (u * 2 <= size && h[u * 2] < h[min]) min = u * 2;//左子节点存在并且小于当前结点,更新min的下标if (u * 2 + 1 <= size && h[u * 2 + 1] < h[min]) min = u * 2 + 1;//右子节点存在并且小于当前结点,更新min的下标if (min != u) {//如果min==u意味着不用变动,u就是三个结点中拥有最小值的结点下标,否则交换数值int temp = h[min];h[min] = h[u];h[u] = temp;down(min);//交换数值后,min这个结点存储原本u的值,u存储存储min的值(三个数中的最小值)。u不用调整了,但min情况不明,可能需要调整。直到它比左右子节点都小}}
}

这篇关于Acwing---838. 堆排序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/700077

相关文章

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

【AcWing】851. 求最短路

spfa算法其实是对贝尔曼福特算法做一个优化。 贝尔曼福特算法会遍历所有边来更新,但是每一次迭代的话我不一定每条边都会更新,SPFA是对这个做优化。 如果说dist[b]在当前这次迭代想变小的话,那么一定是dist[a]变小了,只有a变小了,a的后继(b)才会变小。 用宽搜来做优化,用一个队列,队列里边存的就是所有变小了的结点(队列里存的是待更新的点)。 基本思路就是我更新过谁,我再拿

优先队列与堆排序

PriorityQueue 优先级队列中的元素可以按照任意的顺序插入,却总是按照排序的顺序进行检索。无论何时调用remove方法,总会获得当前优先级队列中的最小元素(其实是返回堆顶元素),但并不是对所有元素都排序。它是采用了堆(一个可以自我调整的二叉树),执行增加删除操作后,可以让最小元素移动到根。 堆排序复习 package com.jefflee;import java.util.Arr

【AcWing】852. spfa判断负环

#include<iostream>#include<algorithm>#include<cstring>#include<queue>using namespace std;const int N= 1e5+10;int n,m;int h[N],w[N],e[N],ne[N],idx;int dist[N],cnt[N];//cnt存最短路径的边数bool st[N];v

6.2排序——选择排序与堆排序

本篇博客梳理选择排序,包括直接选择排序与堆排序 排序全部默认排成升序 一、直接选择排序 1.算法思想 每次遍历都选出最小的和最大的,放到序列最前面/最后面 2.具体操作 (1)单趟 每次遍历都选出最小的和最大的。遍历时,遇到更小的,更新min,遇到更大的,更新max (2)单趟变整体 每趟遍历完之后,begin++,end– 程序结构如下 while(begin<end){//

堆与堆排序之初见

堆(本文只提二叉堆,当然也有多叉堆)作为一种数据结构,是一个数组,可以被看成是一个近似的完全二叉树,树上的每一个节点对应数组中的一个元素,并且除了最底层节点外,该树是完全充满的,而且是从左向右依次填充。 我们目前经常听到的名词“堆”已经被引申为“垃圾收集存储机制”,但本文提及的“堆”指的是堆数据结构。 为了后续描述方便,我们定义堆的数组为H,用H.length表示堆数组的大小,用H.size表示堆

leetcode解题思路分析(九十六)832 - 838 题

翻转图像 给定一个二进制矩阵 A,我们想先水平翻转图像,然后反转图像并返回结果。水平翻转图片就是将图片的每一行都进行翻转,即逆序。例如,水平翻转 [1, 1, 0] 的结果是 [0, 1, 1]。反转图片的意思是图片中的 0 全部被 1 替换, 1 全部被 0 替换。例如,反转 [0, 1, 1] 的结果是 [1, 0, 0]。 在一次遍历中,即进行逆序也进行值的反转,用双指针完成任务 cla

堆排序算法剖析(基于Java)

什么是堆结构? 堆排序的关键是构造堆结构,首先谈一下堆结构的定义,堆结构是一种树结构,准确地说是一个完全二叉树,完全二叉树的定义在这里就不多赘述了,百度知道。 按照排序顺序,堆结构可以分为两种: 1.按照从小到大的顺序排序,要求非叶节点的数据要大于或等于其左、右子节点的数据。 2.按照从大到小的顺序排序,要求非叶节点的数据要小于或等于其左、右子节点的数据。 本文以从小到大的顺序为例进行介

排序算法(动图详细讲解)(直接插入排序,希尔排序,堆排序,冒泡排序)

前言:         排序的方式有很多种,不同的排序思想是不一样的。         但是排序的时间复杂度和空间复杂度也都有区别。         例如:         最简单的冒泡排序,时间复杂度为O(N)         对排序的时间复杂度为O(N*logN)。 接下来就来仔细分析每种排序的思路,并写出代码。 插入排序:  基本思想:         直接插入排序是一种简

堆的建立、插入、出堆、堆化、topk问题、堆排序(C语言实现)

堆的建立、插入、出堆、堆化、topk问题、堆排序 使用数组来存储堆 堆顶为序号0,堆底为序号 size - 1 假设树为完全二叉树,当前节点和双亲节点的关系可以通过公式表达 // 小顶堆: 对 heaptifyUp 和 heaptifyDown 函数的逻辑进行一些调整。void initHeap(float **arr, int *size) { *arr = (float *)malloc