Acwing.838.堆排序

这篇具有很好参考价值的文章主要介绍了Acwing.838.堆排序。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

基础堆操作

题目

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

题解

import java.util.Scanner;

/**
 * @author akuya
 * @create 2023-06-28-14:15
 */
public class heap {
    static int N=100010;
    static int n,m,size=0;
    static int h[]=new int[N];
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        n=scanner.nextInt();
        m=scanner.nextInt();
        size=n;
        for(int i=1;i<=n;i++)h[i]=scanner.nextInt();
        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);
        }

    }
    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(u!=t){
            swap(h,u,t);
            down(t);
        }
    }

    public static void up(int u){
        while(u/2!=0&&h[u/2]>h[u]){
            swap(h,u/2,u);
            u/=2;
        }
    }


    public static void swap(int arr[],int x,int y){
        arr[x]=arr[x]^arr[y];
        arr[y]=arr[x]^arr[y];
        arr[x]=arr[x]^arr[y];
    }


}

进阶 模拟堆

题目

维护一个集合,初始时集合为空,支持如下几种操作:
1."l ×”,插入一个数x;
2."PM”,输出当前集合中的最小值;
3.“DM”,删除当前集合中的最小值(当最小值不唯一时,删除最早插入的最小值);
4."D k”,删除第k个插入的数;
5."C k x”,修改第k个插入的数,将其变为x;

现在要进行N次操作,对于所有第2个操作,输出当前集合的最小值。

输入格式

第一行包含整数N。
接下来N行,每行包含一个操作指令,操作指令为"l x”,“PM”,“DM”,"D k"或"C k x"中的一种。

输出格式

对于每个输出指令"PM”,输出一个结果,表示当前集合中的最小值。每个结果占一行。

数据范围

1≤N≤105-109<a ≤ 109数据保证合法。

  • 输入样例:
8
I -10
PM
I -10
D 1
C 2 8
I 6
PM
DM
  • 输出样例:
-10
6

题解

 import java.util.Scanner;

/**
 * @author akuya
 * @create 2023-06-28-14:15
 */
public class heap {
    static int N=100010;
    static int n,m,size=0;
    static int h[]=new int[N];
    static int ph[]=new int[N];
    static int hp[]=new int[N];

    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        n=scanner.nextInt();
        m=0;
        while(n--!=0){
            String op=scanner.next();
            int k,x;
            if(op.equals("I")){
                x=scanner.nextInt();
                size++;//记录下标
                m++;//记录第几个插入的数
                ph[m]=size;
                hp[size]=m;
                h[size]=x;
                up(size);

            }else if(op.equals("PM")) System.out.println(h[1]);
            else if(op.equals("DM")){
                heap_swap(h,1,size);
                size--;
                down(1);
            }else if(op.equals("D")){
                k=scanner.nextInt();
                k=ph[k];
                heap_swap(h,k,size);
                size--;
                down(k);
                up(k);
            }else{
                k=scanner.nextInt();
                x=scanner.nextInt();
                k=ph[k];
                h[k]=x;
                down(k);
                up(k);
            }

        }

    }
    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(u!=t){
            heap_swap(h,u,t);
            down(t);
        }
    }

    public static void up(int u){
        while(u/2!=0&&h[u/2]>h[u]){
            heap_swap(h,u/2,u);
            u/=2;
        }
    }


    public static void swap(int arr[],int x,int y){
        arr[x]=arr[x]^arr[y];
        arr[y]=arr[x]^arr[y];
        arr[x]=arr[x]^arr[y];
    }

    public static void heap_swap(int arr[],int a,int b){
        swap(ph,hp[a],hp[b]);
        swap(hp,a,b);
        swap(h,a,b);

    }



}

思路

将基础堆排序模板中三个方法修改为如下方法,即可实现进阶堆排序,多了两个数组ph,hp。
ph[k]:第K个插入的点在堆中的下标是什么。
hp[k]:下标为K的点事第几个插入的。
通过ph与hp即可实现进阶题目的后两个操作。文章来源地址https://www.toymoban.com/news/detail-520924.html

到了这里,关于Acwing.838.堆排序的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【AcWing算法基础课】第二章 数据结构(部分待更)

    本专栏文章为本人AcWing算法基础课的学习笔记,课程地址在这。如有侵权,立即删除。 邻接表 :存储图和树 e数组存储每个结点的值,ne数组存储每个结点的指向的下一个结点。 数组模拟链表比较快,指针模拟会涉及到new操作,比较慢。 题目链接 :826. 单链表 1.1题目描述

    2024年02月13日
    浏览(50)
  • 【Java数据结构与算法】Day2-高级排序(希尔、归并、快速、计数)

    ✅作者简介:热爱Java后端开发的一名学习者,大家可以跟我一起讨论各种问题喔。 🍎个人主页:Hhzzy99 🍊个人信条:坚持就是胜利! 💞当前专栏:【Java数据结构与算法】 🥭本文内容:Java数据结构与算法中的比较高级的排序,希尔排序、归并排序、快速排序、计数排序

    2024年02月02日
    浏览(64)
  • AcWing 算法基础课二 数据结构 链表 栈 队列 并查集 哈希表

    链表题目:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 AcWing. 826.单链表 双链表 AcWing 827.双链表 AcWing 828.模拟栈 AcWing 3302.表达式求值 AcWing 829. 模拟队列 AcWing 830.单调栈 AcWing 154.滑动窗口 AcWing 831. KMP字符串 AcWing 835. Trie字符串统计 AcWing 143. 最大异或对 AcWing 836.合并集合

    2024年02月15日
    浏览(50)
  • 数据结构——排序算法——归并排序

    在第二个列表向第一个列表逐个插入的过程中,由于第二个列表已经有序,所以后续插入的元素一定不会在前面插入的元素之前。在逐个插入的过程中,每次插入时,只需要从上次插入的位置开始,继续向后寻找插入位置即可。这样一来,我们最多只需要将两个有序数组遍历

    2024年02月09日
    浏览(47)
  • 【排序算法】数据结构排序详解

    前言: 今天我们将讲解我们数据结构初阶的最后一部分知识的学习,也是最为“炸裂”的知识---------排序算法的讲解!!!! 排序 :所谓排序,就是使一串记录,按照其中的某个或某些的大小,递增或递减的排列起来的操作。 稳定性 :假定在待排序的记录序列中,

    2023年04月08日
    浏览(50)
  • 数据结构和算法笔记4:排序算法-归并排序

    归并排序算法完全遵循分治模式。直观上其操作如下: 分解:分解待排序的n个元素的序列成各具n/2个元素的两个子序列。 解决:使用归并排序递归地排序两个子序列。 合并:合并两个已排序的子序列以产生已排序的答案。 我们直接来看例子理解算法的过程,下面是要排序

    2024年01月21日
    浏览(64)
  • 【数据结构与算法】十大经典排序算法-希尔排序

    🌟 个人博客: www.hellocode.top 🏰 Java知识导航: Java-Navigate 🔥 CSDN: HelloCode. 🌞 知乎 :HelloCode 🌴 掘金 :HelloCode ⚡如有问题,欢迎指正,一起学习~~ 希尔排序是一种插入排序的改进版本,旨在解决插入排序在处理大规模数据时的效率问题。通过将数组分为多个子序列并对

    2024年02月12日
    浏览(80)
  • 【数据结构与算法】十大经典排序算法-快速排序

    🌟 个人博客: www.hellocode.top 🏰 Java知识导航: Java-Navigate 🔥 CSDN: HelloCode. 🌞 知乎 :HelloCode 🌴 掘金 :HelloCode ⚡如有问题,欢迎指正,一起学习~~ 快速排序(Quick Sort)是一种高效的排序算法,是对冒泡排序的优化。它采用分治法(Divide and Conquer)的思想,将待排序序列

    2024年02月13日
    浏览(65)
  • 【数据结构与算法】十大经典排序算法-冒泡排序

    🌟 个人博客: www.hellocode.top 🏰 Java知识导航: Java-Navigate 🔥 CSDN: HelloCode. 🌴 掘金 :HelloCode 🌞 知乎 :HelloCode ⚡如有问题,欢迎指正,一起学习~~ 冒泡排序(Bubble Sort)是一种简单的排序算法,它通过重复地交换相邻元素的位置来将最大(或最小)的元素逐步“冒泡”到

    2024年02月14日
    浏览(75)
  • 【数据结构与算法】十大经典排序算法-插入排序

    🌟 个人博客: www.hellocode.top 🏰 Java知识导航: Java-Navigate 🔥 CSDN: HelloCode. 🌞 知乎 :HelloCode 🌴 掘金 :HelloCode ⚡如有问题,欢迎指正,一起学习~~ 插入排序(Insertion Sort)是一种简单直观的排序算法,其基本思想是将一个记录插入到已排好序的有序序列中,直到所有记录

    2024年02月13日
    浏览(83)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包