优先级队列(堆)的概念+模拟堆的实现

news/2024/5/20 8:53:44 标签: 数据结构, java, , 优先级队列

文章目录


优先级队列)的概念+模拟的实现


一、概念

1.优先级队列

优先级队列 Priority Queue

  • 队列中操作的数据带有优先级,出队的时候,优先级高的先出
  • 可以返回最高优先级对象,可以添加新的对象
  • 在Java1.8中,priorityQueue的底层使用了的相当于对完全二叉树进行了调整

2.

  • 将一个关键码的集合中所以元素,按照完全二叉树的顺序,存进一个一维数组当中

1.的性质

1.中结点的值,总是不大于/不小于它父亲结点的值

2.总是一棵完全二叉树

在这里插入图片描述

2.的存储

  • 是一棵完全二叉树,层序的规则可以用顺序的方法来存储

  • 完全二叉树从上到下,从左往右依次排列,存进数组中没有空的位置

  • 结点在数组下标为i,其双亲结点为( i - 1 )/ 2

  • 左孩子:2 * i +1 ; 右孩子:2 * i + 2

3.的创建

3.1 向下调整

每棵树都向下调整,维护大根

  • 向下调整的时间复杂度:== 树的高度

  • 向下调整建的时间复杂度:O(n)

在这里插入图片描述

  • 每棵树从父结点向下走,要找到每棵树的父结点

  • 从最后一棵子树来进行调整,找到最后一个结点和它的双亲结点,遍历得到父结点的下标

  • 找到最大的子节点,比较后进行交换

java">public class TestHeap {
    public int[] elem;//底层是一个一维数组
    public int usedSize;//记录当前中有多少条数据

    public TestHeap() {
        this.elem = new int[10];
    }

    public void initElem(int[] array) {//初始化
        for (int i = 0; i < array.length; i++) {
            elem[i] = array[i];
            usedSize++;
        }
    }
}

1.进行初始化

java">    public void createHeap() {//的创建
        //最后一个结点的下标= usedSize-1,它的双亲结点的下标= (usedSize-1-1)/2
        for (int parent = (usedSize - 1 - 1) / 2; parent >= 0; parent--) {//求出parent
            shiftDown(parent, usedSize);//结束下标传usedSize
            //结束的结点下标的值不会超过usedSize
        }
    }

    /**
     * 父亲下标
     * 每棵树的结束下标
     *
     * @param parent
     * @param len
     */
    private void shiftDown(int parent, int len) {//向下调整,每棵树从父结点向下走
        int child = 2 * parent + 1;
        // child < len最起码要有一个左孩子
        while (child < len) {
            //child + 1保证一定有右孩子的情况下,和右孩子比较
            if (child + 1 < len && elem[child] < elem[child + 1]) {//右孩子大
                child++;
            }
            //保证child的下标是左右孩子最大值的下标
            if (elem[child] > elem[parent]) {//如果子节点的值比父结点的大,交换
                int tmp = elem[child];
                elem[child] = elem[parent];
                elem[parent] = tmp;

                parent = child;//交换完成后,让parent结点等于等于当前child结点,
                child = 2 * parent + 1;//重新求子节点的位置,再次进入循环交换

            } else {
                break;//比父结点小,结束循环
            }
        }
    }

的创建

1.遍历得到每个双亲结点,根据双亲结点找到子节点,保证child的下标是左右孩子最大值的下标

2.子节点和父结点比较并交换

3.2建的时间复杂度 O(N)

向下调整的方式建立大根、小根,时间复杂度约等于O(n)

在这里插入图片描述

用满二叉树来分析

4.的插入

java">    public void offer(int val) {
        if (isFull()) {//如果满了就扩容
            elem = Arrays.copyOf(elem, 2 * elem.length);
        }
        elem[usedSize++] = val;//存到最后
        //进行向上调整
        shiftUp(usedSize - 1);//传进孩子结点的下标

    }

    public boolean isFull() {
        return usedSize == elem.length;
    }

    private void shiftUp(int child) {//向上调整,已知孩子结点的下标求父亲结点的下标
        int parent = (child - 1) / 2;
        while (child > 0) {//循环结束的条件就是child =0
            if (elem[child] > elem[parent]) {//比较、交换
                int tmp = elem[child];
                elem[child] = elem[parent];
                elem[parent] = tmp;
                child = parent;
                parent = (child - 1) / 2;
            } else {
                break;
            }
        }
    }
4.1向上调整
  • 插入到有效数据的最后,空间不够要扩容,成为新的子节点,已知孩子结点,求父亲结点
  • 向上调整,调整的过程中,直接和父结点比较,如果比父结点的值大就交换
  • 不用比较左右孩子的最大值,因为根节点的子树本身就是大根,不用进行维护
4.2向上调整建的时间复杂度:O(N * log N)

在这里插入图片描述

5.的删除

  • 1.的删除,删除的是顶元素
  • 2.将0下标和最后一个元素的下标进行交换,将中有效数据个数减少一个
  • 3.对顶元素进行向下调整,只需要调整0下标的数
java">    /**
     * 删除顶
     */
    public void pop() {
        if (isEmpty()) {
            return;
        }
        swap(elem, 0, usedSize - 1);//顶和最后一个元素交换
        usedSize--;//删除一个元素
        shiftDown(0, usedSize);//向下调整
    }

    public boolean isEmpty() {
        return usedSize == 0;
    }

    private void swap(int[] array, int i, int j) {
        int tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }

    public int peek() {
        if (isEmpty()) {
            return -1;
        }
        return elem[0];
    }

点击移步博客主页,欢迎光临~

偷cyk的图


http://www.niftyadmin.cn/n/5154176.html

相关文章

1.UML面向对象类图和关系

文章目录 4种静态结构图类图类的表示类与类之间的关系依赖关系(Dependency)关联关系(Association)聚合(Aggregation)组合(Composition)实现(Realization)继承/泛化(Inheritance/Generalization)常用的UML工具reference欢迎访问个人网络日志🌹🌹知行空间🌹🌹 4种静态结构…

ubuntu挂载共享目录的方法

ubuntu挂载共享目录的方法 安装NFS配置NFS 安装NFS sudo apt-get install nfs-kernel-server配置NFS 创建work共享目录:(本人将此文件放在桌面)sudo mkdir worksudo gedit /etc/exports添加: /home/zynq/Desktop/work *(rw,sync,no_root_squash,no_subtree_check)运行以下命…

运动重定向:TeachNet

Vision-based Teleoperation of Shadow Dexterous Hand using End-to-End Deep Neural Network解析 摘要1. 简介2. Related Work2.1 基于视觉的无标记远程操作2.2 基于深度的3D手部姿势估计2.3 远程操作中的主从配对2.4 遥操作映射方法 3. 师生网络Joint angle lossConsistency…

ICCV2023 Tracking paper汇总(一)(多目标跟随、单目标跟随等)

一、PVT: A Simple End-to-End Latency-Aware Visual Tracking Framework paper&#xff1a; https://openaccess.thecvf.com/content/ICCV2023/papers/Li_PVT_A_Simple_End-to-End_Latency-Aware_Visual_Tracking_Framework_ICCV_2023_paper.pdf github&#xff1a; https://…

6.2 创建和销毁互斥量

方法 pthread_mutex_init(mutex, attr) pthread_mutex_destroy(mutex) pthread_mutexattr_init(attr) pthread_mutexattr_destroy(attr) 用法 互斥量的类型为pthread_mutex_t&#xff0c;必须在使用前初始化。有如下两种初始化互斥量的方法&#xff1a; 声明时初始化&…

[Linux打怪升级之路]-信号的产生

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、信号基础…

Java基础-015-System.java常用类

Java基础-015-System.java常用类 1、标准输入输出2、获取属性3、System.java初始化4、设置标准输出System.out java/lang/System.java 1、标准输入输出 System.in、System.out public class Test {public static void main(String[] args) {String charsetName String.valueOf…

【Java 进阶篇】JSP 简单入门

在现代Web开发中&#xff0c;JavaServer Pages&#xff08;JSP&#xff09;是一项非常重要的技术。JSP允许开发者将Java代码嵌入HTML页面&#xff0c;以实现动态内容的生成和呈现。本文将详细介绍JSP的概念、原理以及如何使用JSP来构建Web应用程序。 第一部分&#xff1a;JSP …