迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > Java >

在 Java 中实现最小堆

作者:迹忆客 最近更新:2023/11/28 浏览次数:

最小堆是其中每个内部节点都小于或等于其子节点值的堆。我们将在以下几点中看到如何使用和不使用库来实现最小堆。


Java 中不使用库的最小堆实现

在这个例子中,我们看到了不使用任何库的实现。在这里,我们创建了一个类 JavaMinHeap,我们在其中创建了三个实例变量 HeapArray 是一个 int 类型的数组,它将保留堆的所有值,size 是堆的大小,maxSize 存储 HeapArray 的最大大小。我们还创建了一个类型为 intstatic 变量 FRONT 并将其初始化为 1。

我们在构造函数中获取 maxSize 作为参数并将其存储在实例变量 maxSize 中。我们用 0 初始化 size,用 maxSize + 1 大小的 int 数组初始化 HeapArray。我们将 Integer 的最小值存储在 HeapArray 的第一个索引处。

现在我们创建方法来在堆上执行操作。parent() 函数将 position 作为参数,并返回节点所传递位置的父节点。然后我们创建 leftChild(),它返回作为参数接收到的位置的左孩子。使用 rightChild() 返回 (2 * position) + 1 节点值的右子节点也是如此。

isLeaf() 检查一个节点是否是叶子节点,这意味着它有任何子节点。swapNodes() 是一种将位置 fpos 的节点值与位置 spos 交换的方法。在方法中,我们创建了一个 temp 变量并初始化它,HeapArrayfpos 位置,并将 HeapArrayspos 值存储到 HeapArray[fpos]。现在我们将 temp 值存储在 HeapArray[spos] 中。

convertToMinHeap() 使用 isLeaf 检查作为参数接收的位置是否是叶子,如果不是,则检查 HeapArray 位置的当前值是否大于左孩子或右孩子。然后我们检查左孩子是否小于右孩子,如果是,我们使用 swapNodes() 来交换节点并在 position 处传递 position 和左孩子。我们再次使用 convertToMinHeap() 将接收到的左子节点转换为最小堆。

我们使用 insert() 将值插入到最小堆中。在 insert() 中,如果数组达到 maxSize,我们不插入就返回;如果没有,我们在 ++size 处获取位置并将接收到的元素插入 HeapArray[++size]。我们把尺寸放到当前。如果当前位置的元素小于其父元素,我们将创建一个循环并交换节点。

为了打印最小堆,我们创建 printheap() 并循环遍历 HeapArray,其中父项位于 ith 位置,左子项位于 2 * i 位置,右子项是在 2 * i + 1 位置。在 main() 函数中,我们使用 insert() 在堆中插入元素。

public class JavaMinHeap {
  private final int[] HeapArray;
  private int size;
  private final int maxsize;

  private static final int FRONT = 1;

  public JavaMinHeap(int maxsize) {
    this.maxsize = maxsize;
    this.size = 0;
    HeapArray = new int[this.maxsize + 1];
    HeapArray[0] = Integer.MIN_VALUE;
  }

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

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

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

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

  private void swapNodes(int fpos, int spos) {
    int temp;
    temp = HeapArray[fpos];
    HeapArray[fpos] = HeapArray[spos];
    HeapArray[spos] = temp;
  }

  private void convertToMinHeap(int position) {
    if (!isLeaf(position)) {
      if (HeapArray[position] > HeapArray[leftChild(position)]
          || HeapArray[position] > HeapArray[rightChild(position)]) {
        if (HeapArray[leftChild(position)] < HeapArray[rightChild(position)]) {
          swapNodes(position, leftChild(position));
          convertToMinHeap(leftChild(position));
        } else {
          swapNodes(position, rightChild(position));
          convertToMinHeap(rightChild(position));
        }
      }
    }
  }

  public void insert(int element) {
    if (size >= maxsize) {
      return;
    }
    HeapArray[++size] = element;
    int current = size;

    while (HeapArray[current] < HeapArray[parent(current)]) {
      swapNodes(current, parent(current));
      current = parent(current);
    }
  }

  public void printHeap() {
    for (int i = 1; i <= size / 2; i++) {
      System.out.println("PARENT : " + HeapArray[i]);

      System.out.println("--LEFT CHILD : " + HeapArray[2 * i]);

      System.out.println("--RIGHT CHILD : " + HeapArray[2 * i + 1]);
      System.out.println();
    }
  }

  public static void main(String[] arg) {
    System.out.println("The Min Heap is ");
    JavaMinHeap minHeap = new JavaMinHeap(10);
    minHeap.insert(10);
    minHeap.insert(2);
    minHeap.insert(7);
    minHeap.insert(15);
    minHeap.insert(90);
    minHeap.insert(19);
    minHeap.insert(8);
    minHeap.insert(22);
    minHeap.insert(9);

    minHeap.printHeap();
  }
}

输出:

The Min Heap is 
PARENT : 2
--LEFT CHILD : 9
--RIGHT CHILD : 7

PARENT : 9
--LEFT CHILD : 10
--RIGHT CHILD : 90

PARENT : 7
--LEFT CHILD : 19
--RIGHT CHILD : 8

PARENT : 10
--LEFT CHILD : 22
--RIGHT CHILD : 15

Java 中使用 PriorityQueue 实现最小堆

在这个程序中,我们使用用于创建最大和最小堆的 PriorityQueuePriorityQueue 提供了多个类似 add() 将元素插入队列的方法,peek() 获取队列的头部并将其删除,poll() 也检索队列的头部但不删除它. contains() 检查它指定的元素是队列。remove() 删除指定的元素。

我们结合 PriorityQueue 的所有功能来创建和执行最小堆操作。首先,我们使用 new PriorityQueue() 创建一个 Integer 类型的空 priorityQueue 对象。然后我们使用 add() 方法添加我们的元素。为了打印和移除队列头,我们调用打印 10 的 priorityQueue.peek()。然后我们使用增强的 for 打印队列的所有元素。现在我们调用 poll() 打印并删除 10。然后我们从队列中删除一个元素。我们使用返回 booleancontains() 来检查元素是否在队列中。最后,为了打印剩余的值,我们使用 toArray() 将队列转换为数组。

import java.util.*;

public class JavaMinHeap {
  public static void main(String[] args) {
    PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();

    priorityQueue.add(10);
    priorityQueue.add(15);
    priorityQueue.add(25);
    priorityQueue.add(200);

    System.out.println("The head value using peek(): " + priorityQueue.peek());

    System.out.println("The queue elements: ");
    for (Integer integer : priorityQueue) System.out.println(integer);

    priorityQueue.poll();
    System.out.println("After removing the head element using poll(): ");
    for (Integer integer : priorityQueue) System.out.println(integer);

    priorityQueue.remove(25);
    System.out.println("After removing 25 with remove(): ");
    for (Integer integer : priorityQueue) System.out.println(integer);

    boolean b = priorityQueue.contains(15);
    System.out.println("Check if priorityQueue contains 15 using contains():  " + b);

    Object[] arr = priorityQueue.toArray();
    System.out.println("Values in array: ");
    for (Object o : arr) System.out.println("Value: " + o.toString());
  }
}

输出:

The head value using peek(): 10
The queue elements: 
10
15
25
200
After removing the head element using poll(): 
15
200
25
After removing 25 with remove(): 
15
200
Check if priorityQueue contains 15 using contains():  true
Values in array: 
Value: 15
Value: 200

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

Java 中的类字段和实例字段

发布时间:2023/11/28 浏览次数:97 分类:Java

在本文中,你将学习一些 Java 术语,它们是局部变量、输入参数、类字段和实例字段。我们还将讨论 Java 中实例字段的一些属性。

Java 中的类文件编辑器

发布时间:2023/11/28 浏览次数:192 分类:Java

本文展示了如何使用 Java 类文件来编辑类文件。在本文中,我们将讨论 Java 类文件编辑器,这是一个用 Java 创建的工具,用于编辑 Java 编译的类。我们可以在创建 Java 类后对其进行反编译并查看

Java 中的_JAVA_OPTIONS 环境变量

发布时间:2023/11/28 浏览次数:166 分类:Java

在本文中,我们将讨论 Java 选项和 _JAVA_OPTIONS 环境变量,它的后续 JAVA_TOOL_OPTIONS 和 JDK_JAVA_OPTIONS。

如何在 Java 中清除控制台

发布时间:2023/11/28 浏览次数:125 分类:Java

它展示了在 Java 中清理控制台屏幕的两种方法。在本教程中,我们将看一下在 Java 中清理控制台屏幕的两种方法。我们将通过实例来学习如何在运行时执行 Java 清屏命令。

如何在 Java 中从控制台获取输入

发布时间:2023/11/28 浏览次数:163 分类:Java

本教程展示了 Scanner 类中包含的读取控制台输入的各种功能。在本教程中,我们将查看 Java 中的 Scanner 类,并学习如何使用该类从控制台读取输入。Scanner 类来自于 Java 包 java.util.Scanner。

Java 中的 console.log

发布时间:2023/11/28 浏览次数:174 分类:Java

本文介绍 Java 中的 console.log。本教程介绍 Java 中的 console.log() 函数以及如何在 Java 中将日志显示到控制台。console.log() 是 JavaScript 的一个函数,用于向浏览器控制台显示日志消息。

Java 更改日期格式

发布时间:2023/11/28 浏览次数:166 分类:Java

本文介绍如何在 Java 中更改日期格式 有多种选项可用于将日期字符串转换为日期格式。下面提到的方法可以带来所需的结果。让我们从下面的代码块中了解各种方式。

Java 中 YYYY-MM-DD 格式的日历日期

发布时间:2023/11/28 浏览次数:157 分类:Java

本文讨论了我们可以在 Java 中将日历日期转换为 YYYY-MM-DD 格式的各种方法。Java Date 封装了当前时间和日期。日期类在两个构造函数的帮助下做到这一点 - Date() 和 Date(long millisec) 构造函数。

在 Java 中实现最小最大堆

发布时间:2023/11/28 浏览次数:50 分类:Java

本文介绍如何在 Java 中实现最小最大堆 本文将使用 PriorityQueue 类实现一个最大堆和一个最小堆。我们还将演示从堆中插入和删除元素。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便