Java数据结构之堆(优先队列)的实现

Java 数据结构之堆(优先队列)的实现

什么是堆(优先队列)

堆(Heap)是一种数据结构,使用数组实现。堆分为小根堆和大根堆,大根堆满足父节点值大于子节点,小根堆则相反。堆通常被用来实现优先队列(Priority Queue)。

优先队列(Priority Queue)是一个能够让用户迅速查找到队列中最小值(或最大值)的抽象数据类型(ADT)。优先队列通常用堆来实现。

在Java中,堆的实现主要有两种方式:一种是使用Collections的PriorityQueue,一种是手动实现堆。

java.util.PriorityQueue实现

Java中自带的PriorityQueue是一种实现了优先队列的数据结构,底层是一个小根堆。它的具体实现是数组,也可以用数组表达式来看待这个堆 。Java中的PriorityQueue提供了数据结构基本操作的方法:插入、删除、获取队首元素、堆大小等。

下面是Java实现PriorityQueue的示例代码:

import java.util.PriorityQueue;
public class Main {
    public static void main(String[] args) {
        PriorityQueue<Integer> pq = new PriorityQueue<>();
        pq.add(3);
        pq.add(1);
        pq.add(2);
        System.out.println(pq);
        System.out.println(pq.poll());
        System.out.println(pq.poll());
        System.out.println(pq.poll());
    }
}

输出结果:

[1, 3, 2]
1
2
3

上面的示例代码首先创建了一个PriorityQueue对象pq,然后通过add()方法插入元素。最后三个poll()方法依次弹出元素。这里需要注意的是,PriorityQueue是小根堆,poll()方法会弹出堆中的最小元素。

手动实现堆

手动实现堆的方式在工程实践中不常用,但是可以增加对堆的深刻理解。

下面是手动实现堆的示例代码:

public class Heap {
    private int[] heap;
    private int size;
    private int maxSize;

    public Heap(int maxSize) {
        this.maxSize = maxSize;
        this.size = 0;
        this.heap = new int[this.maxSize + 1];
        this.heap[0] = Integer.MIN_VALUE;
    }

    private int parent(int i) {
        return i / 2;
    }

    private int leftChild(int i) {
        return i * 2;
    }

    private int rightChild(int i) {
        return (i * 2) + 1;
    }

    private boolean isLeaf(int i) {
        if (i > size / 2 && i <= size) {
            return true;
        }
        return false;
    }

    private void swap(int i, int j) {
        int temp = this.heap[i];
        this.heap[i] = this.heap[j];
        this.heap[j] = temp;
    }

    public void insert(int element) {
        if (size >= maxSize) {
            return;
        }
        this.heap[++size] = element;
        int current = size;
        while (this.heap[current] < this.heap[parent(current)]) {
            swap(current, parent(current));
            current = parent(current);
        }
    }

    public int remove() {
        int popped = this.heap[1];
        this.heap[1] = this.heap[size--];
        heapify(1);
        return popped;
    }

    public void heapify(int i) {
        if (!isLeaf(i)) {
            if (this.heap[i] > this.heap[leftChild(i)] || this.heap[i] > this.heap[rightChild(i)]) {
                if (this.heap[leftChild(i)] < this.heap[rightChild(i)]) {
                    swap(i, leftChild(i));
                    heapify(leftChild(i));
                } else {
                    swap(i, rightChild(i));
                    heapify(rightChild(i));
                }
            }
        }
    }

    public void print() {
        for (int i = 1; i <= size / 2; i++) {
            System.out.print(" PARENT : " + heap[i] + " LEFT CHILD : " + heap[2 * i]
                    + " RIGHT CHILD :" + heap[2 * i + 1]);
            System.out.println();
        }
    }

    public static void main(String[] args) {
        Heap Heap = new Heap(15);
        Heap.insert(5);
        Heap.insert(3);
        Heap.insert(17);
        Heap.insert(10);
        Heap.insert(84);
        Heap.insert(19);
        Heap.insert(6);
        Heap.insert(22);
        Heap.insert(9);

        Heap.print();

        System.out.println("The Min val is " + Heap.remove());
    }
}

输出结果:

 PARENT : 3 LEFT CHILD : 5 RIGHT CHILD :17
 PARENT : 5 LEFT CHILD : 10 RIGHT CHILD :84
 PARENT : 17 LEFT CHILD : 6 RIGHT CHILD :19
 PARENT : 10 LEFT CHILD : 22 RIGHT CHILD :9
The Min val is 3

上面的代码实现了手动创建堆和一些基本操作的方法,例如:insert()、remove()、heapify()以及print()操作。我们可以看到,输出的结果是小根堆的形式,remove()方法会返回堆中的最小元素。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java数据结构之堆(优先队列)的实现 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • redis中的数据结构和编码详解

    Redis中的数据结构和编码详解 Redis中的数据结构 Redis支持以下五种数据结构: 字符串(string):最基本的数据类型,Redis中的字符串是二进制安全的,意味着您可以在字符串中存储任何数据。例如,您可以将图像文件或序列化对象存储为Redis字符串。字符串最大可以容纳512MB。 列表(list):Redis列表是字符串列表,其中的元素按照插入…

    数据结构 2023年5月17日
    00
  • 数据结构之数组翻转的实现方法

    下面是数据结构之数组翻转的实现方法的详细攻略。 1. 问题描述 在数组中,将元素以轴对称的方式进行翻转,即将数组的第一个元素和最后一个元素交换,第二个元素和倒数第二个元素交换,以此类推。 例如,对于数组[1, 2, 3, 4, 5],经过翻转后变成[5, 4, 3, 2, 1]。 2. 解法讲解 2.1 方法一:双指针法 双指针法是常用的一种方法,可以实现两…

    数据结构 2023年5月17日
    00
  • Python嵌套式数据结构实例浅析

    Python嵌套式数据结构实例浅析 介绍 在Python中,数据结构是非常重要的。Python中的嵌套数据结构给我们提供了非常灵活的使用方式。例如,我们可以使用嵌套式列表和字典来处理复杂的数据结构问题。在本文中,我将向您介绍Python中嵌套式数据结构的使用方法和示例代码。 嵌套式列表 首先,让我们来看看使用Python中的嵌套式列表。嵌套式列表是列表嵌套的…

    数据结构 2023年5月17日
    00
  • 「学习笔记」数位 DP

    「学习笔记」数位 DP 意义不大的题不写了。 点击查看目录 目录 「学习笔记」数位 DP 概述 例题 P2657 [SCOI2009] windy 数 思路 代码 P4317 花神的数论题 思路 P4124 [CQOI2016]手机号码 思路 代码 haha数 题意 思路 代码 0和1的熟练 题意 思路 代码 苍与红的试炼 题意 思路 代码 概述 数位 DP…

    算法与数据结构 2023年4月17日
    00
  • 京东LBS推荐算法实践

    作者:京东零售 郑书剑 1、推荐LBS业务介绍 1.1 业务场景 现有的同城购业务围绕京东即时零售能力搭建了到店、到家两种业务场景。同城业务与现有业务进行互补,利用高频,时效性快的特点,可以有效提升主站复访复购频次,是零售的重要战略方向。 1.2 名词解释 LBS:基于位置的服务(Location Based Services)。 下文LBS商品代指京东小时…

    算法与数据结构 2023年4月17日
    00
  • C语言数据结构系列之树的概念结构和常见表示方法

    C语言数据结构系列之树的概念结构和常见表示方法 树是一种非线性数据结构,它由若干个节点构成,节点之间通过边来连接,具有层次关系。 树的基本概念和术语 节点:树中的元素,它可以包含一个数据元素或多个数据元素,一个节点也可以称为一个分支节点。 根节点:树的最上层节点,它没有父节点。 叶子节点:没有子节点的节点称为叶子节点。 父节点和子节点:父节点是某个节点的上一…

    数据结构 2023年5月17日
    00
  • C语言数据结构算法基础之循环队列示例

    标题:C语言数据结构算法基础之循环队列示例 1. 简介 循环队列是一种常见的数据结构,它采用固定大小的数组来模拟队列的数据结构,可以高效地处理队列的进出操作。本文将会讲解循环队列的实现原理和示例代码。 2. 循环队列基本原理 循环队列通过两个指针front和rear来实现队列的添加和删除操作。在初始化时,front和rear的初始值都为0。每当数据进入队列时…

    数据结构 2023年5月17日
    00
  • 详解数据结构C语言实现之循环队列

    详解数据结构C语言实现之循环队列 什么是循环队列 循环队列是一种数据结构,它可以存储一组固定大小的元素,并且支持在队列尾部插入元素和在队列头部删除元素,当队列尾部没有空间时可以将队列头部空余的位置用来插入元素,实现循环的效果。循环队列的主要优点在于插入和删除元素的时间复杂度均为O(1),而不是O(n)。 如何实现循环队列 循环队列可以使用数组来实现,需要定义…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部