(Java)数据结构——排序(第一节)堆排序+PTA L2-012 关于堆的判断

这篇具有很好参考价值的文章主要介绍了(Java)数据结构——排序(第一节)堆排序+PTA L2-012 关于堆的判断。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

本博客是博主用于复习数据结构以及算法的博客,如果疏忽出现错误,还望各位指正。

堆排序(Heap Sort)概念

堆排序是一种基于堆数据结构的排序算法,其核心思想是将待排序的序列构建成一个最大堆(或最小堆),然后将堆顶元素与最后一个元素交换,再将剩余元素重新调整为最大堆(或最小堆),重复以上步骤直到所有元素都有序。

堆是一棵完全二叉树,因此一般可以当作数组处理。

对于最大堆,任何一个父节点的值都大于(或等于)其左右子节点的值;

对于最小堆,则是任何一个父节点的值都小于(或等于)其左右子节点的值。

建堆

上滤(插入新元素到堆中)

时间复杂度为O(N logN)

也就是一个一个插入,比如拿[46 23 26 24 10]来说,建堆过程就如下:

(Java)数据结构——排序(第一节)堆排序+PTA L2-012 关于堆的判断,排序,数据结构,数据结构,算法,java,排序算法


        List<Integer> list = new ArrayList<>();
        String[] num = in.nextLine().split(" ");
        
        for(int i = 0;i<N;i++){
            //小顶堆的形成,自上而下建堆,一个一个插入
            if(list.size()==0){
                list.add(Integer.parseInt(num[i]));
            }else{
                //如果长度不是0,就插入后进行比较
                list.add(Integer.parseInt(num[i]));
                int count = i;
                while(count!=0){
                    int parent = 0;
                    if((count-1)%2==0){
                        parent = (count-1)/2;
                    }else if((count-2)%2==0){
                        parent =(count-2)/2;
                    }
                    if(list.get(count)<list.get(parent)){
                        int temp = list.get(count);
                        list.set(count,list.get(parent));
                        list.set(parent,temp);
                        count = parent;
                    }else{
                        break;
                    }
                }
            }
        }

下滤

一般用的是下滤,因为时间复杂度为O(N)

就是先整体插入,然后从倒数第一个非叶子结点进行堆调整:

1、找到倒数第一个非叶子结点23,判断其与子节点关系,发现比10大,于是互换

2、之后继续寻找非叶子结点,找到46,46与10交换后,继续与23交换

(Java)数据结构——排序(第一节)堆排序+PTA L2-012 关于堆的判断,排序,数据结构,数据结构,算法,java,排序算法

注意事项

建堆结束,两种方法建立的堆可能不一样,所以注意题目要求透露出的是哪一种。

比如要求上滤的:L2-012 关于堆的判断 - 团体程序设计天梯赛-练习集 (pintia.cn)

实现代码:

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String[] mn = in.nextLine().split(" ");
        int N = Integer.parseInt(mn[0]);
        int M = Integer.parseInt(mn[1]);
        List<Integer> list = new ArrayList<>();
        String[] num = in.nextLine().split(" ");

        for(int i = 0;i<N;i++){
            //小顶堆的形成
            if(list.size()==0){
                list.add(Integer.parseInt(num[i]));
            }else{
                //如果长度不是0,就进行比较
                list.add(Integer.parseInt(num[i]));
                int count = i;
                while(count!=0){
                    int parent = 0;
                    if((count-1)%2==0){
                        parent = (count-1)/2;
                    }else if((count-2)%2==0){
                        parent =(count-2)/2;
                    }
                    if(list.get(count)<list.get(parent)){
                        int temp = list.get(count);
                        list.set(count,list.get(parent));
                        list.set(parent,temp);
                        count = parent;
                    }else{
                        break;
                    }
                }
            }
        }

        //System.out.println(list.toString());
        //判断
        while(M-->0){
            String[] judge = in.nextLine().split(" ");
            //变成在数组中的下标
            int x = list.indexOf(Integer.parseInt(judge[0]));
            if(judge[3].equals("root")){
                if(x==0){
                    System.out.println("T");
                }else{
                    System.out.println("F");
                }
            }else if(judge[3].equals("are")){
                int y = list.indexOf(Integer.parseInt(judge[2]));
                if((y-1)%2==0){
                    if(y+1==x){
                        System.out.println("T");
                    }else{
                        System.out.println("F");
                    }
                }else if((y-2)%2==0){
                    if(y-1==x){
                        System.out.println("T");
                    }else{
                        System.out.println("F");
                    }
                }
            }else if(judge[3].equals("parent")){
                int y = list.indexOf(Integer.parseInt(judge[5]));
                if((y-1)%2==0){
                    if((y-1)/2==x){
                        System.out.println("T");
                    }else{
                        System.out.println("F");
                    }
                }else if((y-2)%2==0){
                    if((y-2)/2==x){
                        System.out.println("T");
                    }else{
                        System.out.println("F");
                    }
                }
            }else if(judge[3].equals("child")){
                int y = list.indexOf(Integer.parseInt(judge[5]));
                if((2*y+1) == x || (2*y+2)== x){
                    System.out.println("T");
                }else{
                    System.out.println("F");
                }
            }
        }
    }
}

(Java)数据结构——排序(第一节)堆排序+PTA L2-012 关于堆的判断,排序,数据结构,数据结构,算法,java,排序算法

当然,更简单的,可以直接使用Java提供的类,直接使用优先队列toArray解决:

【PTA-训练day1】L2-012 关于堆的判断 + L1-002打印沙漏_pta打印沙漏测试点-CSDN博客

Java优先队列

关于Java优先队列的一篇博主的博客详细介绍

【Java】PriorityQueue--优先级队列_java priorityqueue-CSDN博客

队列是一种先进先出(FIFO)的数据结构 ,但有些情况下, 操作的数据可能带有优先级,一般出队列时,可能需要优先级高的元素先出队列 ,该中场景下,使用队列显然不合适,比如:在手机上玩游戏的时候,如果有来电,那么系统应该优先处理打进来的电话.
在这种情况下, 数据结构应该提供两个最基本的操作,一个是返回最高优先级对象,一个是添加新的对象。 这种数据结构就是 优先级队列(Priority Queue)。

JDK1.8 中的 PriorityQueue底层使用了堆这种数据结构 ,而堆实际就是在完全二叉树的基础上进行了一些调整。

默认情况下是小根堆,如果需要大根堆,则需要构建比较器。

其他方法与队列无异。

PriorityQueue<Integer> q=new PriorityQueue<>(); //默认小顶堆
 
PriorityQueue<Integer> q=new PriorityQueue<>((a,b)->(b-a)); //大顶堆
 
q.contains(val);
 
Integer[] t=q.toArray(new Integer[n]); //将队列转化为数组

堆排序

上述三种建堆的方法,每次之后将最顶点进行一下处理(移除或者加入数组末尾等操作),然后重新建堆再操作即可实现堆排序。

应用场景

堆排序使用场景堆排序的使用场景与其他排序算法类似,适用于需要对大量数据进行排序的场景。比如取出第k大(小)的数,这时候可以用堆排序。

优/缺点

优点主要包括:

时间复杂度较低:堆排序的时间复杂度为 O(NlogN),相对于其他排序算法,其排序速度较快。

不占用额外空间:堆排序是一种原地排序算法,不需要额外的空间来存储排序结果。

适用于大数据量的排序:堆排序的时间复杂度不随数据量的增加而变化,因此适用于大数据量的排序。

缺点主要包括:

不稳定性:由于堆排序是通过交换元素来实现排序的,因此在排序过程中可能会破坏原有的相对顺序,导致排序结果不稳定。

实现复杂:相对于其他排序算法,堆排序的实现稍微复杂一些(不过借助Java提供的优先队列可以简单实现),需要理解堆数据结构的基本原理和实现过程。文章来源地址https://www.toymoban.com/news/detail-848771.html

代码(后续写了再上传,咕咕咕)

到了这里,关于(Java)数据结构——排序(第一节)堆排序+PTA L2-012 关于堆的判断的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • Java基础数据结构之排序

    假定在待排序的记录序列中,存在多个具有相同的的记录,若经过排序,这些记录的相对次序保持 不变,即在原序列中, r[i]=r[j] ,且 r[i] 在 r[j] 之前,而在排序后的序列中, r[i] 仍在 r[j] 之前,则称这种排序算法是稳 定的;否则称为不稳定的。 内部排序 :数据元素

    2024年01月25日
    浏览(44)
  • 算法 数据结构 递归插入排序 java插入排序 递归求解插入排序算法 如何用递归写插入排序 插入排序动图 插入排序优化 数据结构(十)

    1. 插入排序(insertion-sort):                                           是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入     算法稳定性:                  

    2024年02月09日
    浏览(55)
  • Java 与数据结构(6):快速排序

    ChatGPT 中文指南(大全) 内容包含:如何开通chatgpt、chatgpt的同类站点、prompts 、AI绘图、ChatGPT 工具、相关报告论文、ChatGPT应用项目等 链接:ChatGPT 中文指南(大全) 指令指南,精选资源清单,更好的使用 chatGPT 让你的生产力up up up! 快速排序(Quick Sort)是一种基于分治思想的排序

    2024年02月07日
    浏览(38)
  • 【数据结构】用Java实现七大排序算法

    目录 🌷1. 排序的概念及引用 1.1 排序的概念 1.2 衡量指标 1.2 十个排序算法  1.3 十个排序性能对比 🌷2. 冒泡排序 2.1 算法描述 2.2 动图 ⭐️代码优化 🌷3. 选择排序 3.1 算法描述 3.2 动图  3.3 代码 🌷4. 插入排序 4.1 算法描述 4.2 动图  4.3 代码 🌷5 希尔排序 5.1 描述 5.2 动图  

    2023年04月23日
    浏览(54)
  • 【算法与数据结构】Java实现查找与排序

    也叫做折半查找,属于有序查找算法。 前提条件 :数组数据必须有序,从小到大,或者从大到小都是可以的。 如果是无序的,也可以先进行排序。 但是排序之后,会改变原有数据的顺序,查找出来元素位置跟原来的元素可能是不一样的,所以排序之后再查找只能判断当前数

    2024年01月19日
    浏览(50)
  • 数据结构中的七大排序(Java实现)

    目录 一、直接插入排序 二、希尔排序 三、直接选择排序 四、堆排序 五、冒泡排序 六、快速排序 七、归并排序               定义i下标之前的元素全部已经有序 ,遍历一遍要排序的数组,把i下标前的元素全部进行排序,当遍历玩这个数组后,就已经排好序了。        

    2024年02月08日
    浏览(51)
  • 数据结构(超详细讲解!!)第二十一节 特殊矩阵的压缩存储

    值相同的元素只存储一次 压缩掉对零元的存储,只存储非零元 特殊形状矩阵: 是指非零元(如值相同的元素)或零元素分布具有一定规律性的矩阵。 如: 对称矩阵 上三角矩阵   下三角矩阵 对角矩阵   准对角矩阵 三角矩阵大体分为三类:下三角矩阵、上三角矩阵和对称

    2024年02月04日
    浏览(50)
  • 《数据结构》_PTA_数据结构作业6:图

    1-1 无向连通图所有顶点的度之和为偶数。 T 1-2 无向连通图边数一定大于顶点个数减1 F 1-3 无向连通图至少有一个顶点的度为1。 F 1-4 用邻接表法存储图,占用的存储空间数只与图中结点个数有关,而与边数无关. F 1-5 用邻接矩阵法存储图,占用的存储空间数只与图中结点个数

    2024年02月04日
    浏览(56)
  • Java数据结构之排序(头歌平台,详细注释)

    目录 第1关:选择排序 任务描述 相关知识 代码:    第2关:插入排序 任务描述 相关知识 插入排序 代码:   第3关:归并排序 任务描述 相关知识 归并排序 原理 代码:    第4关:快速排序 任务描述 相关知识 快速排序 代码:    第5关:堆排序 任务描述 相关知识 堆

    2024年01月19日
    浏览(40)
  • 数据结构与算法中的七大排序(Java实现)

    目录 一、直接插入排序 二、希尔排序 三、直接选择排序 四、堆排序 五、冒泡排序 六、快速排序 七、归并排序               定义i下标之前的元素全部已经有序 ,遍历一遍要排序的数组,把i下标前的元素全部进行排序,当遍历玩这个数组后,就已经排好序了。        

    2024年02月06日
    浏览(57)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包