Java语言实现最大堆代码示例

让我为您详细讲解“Java语言实现最大堆代码示例”的完整攻略。

最大堆简介

最大堆是一种满足父节点比子节点大的堆,它通常用于对数据进行排序和查找最大值。最大堆可以通过用数组表示、从根节点开始,每次比较左右子节点的大小,决定是否交换它们来实现。

Java实现最大堆代码示例

下面是Java实现最大堆代码的示例:

public class MaxHeap {
    private int[] heapArray;
    private int size;

    public MaxHeap(int maxSize) {
        heapArray = new int[maxSize];
        size = 0;
    }

    public void insert(int value) {
        if (size == heapArray.length) {
            throw new ArrayIndexOutOfBoundsException("Heap is full.");
        }

        heapArray[size] = value;
        int current = size;
        while (heapArray[current] > heapArray[parent(current)]) {
            swap(current, parent(current));
            current = parent(current);
        }
        size++;
    }

    public int remove() {
        if(size == 0) {
            throw new NullPointerException("Heap is empty.");
        }

        int root = heapArray[0];
        heapArray[0] = heapArray[size - 1];
        size--;
        heapify(0);

        return root;
    }

    private void heapify(int pos) {
        if (isLeaf(pos)) {
            return;
        }

        int leftChild = leftChild(pos);
        int rightChild = rightChild(pos);
        int max = pos;
        if (leftChild < size && heapArray[leftChild] > heapArray[max]) {
            max = leftChild;
        }
        if (rightChild < size && heapArray[rightChild] > heapArray[max]) {
            max = rightChild;
        }
        if (max != pos) {
            swap(pos, max);
            heapify(max);
        }
    }

    private int parent(int pos) {
        return (pos - 1) / 2;
    }

    private int leftChild(int pos) {
        return 2 * pos + 1;
    }

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

    private boolean isLeaf(int pos) {
        return pos >= (size / 2) && pos < size;
    }

    private void swap(int a, int b) {
        int temp = heapArray[a];
        heapArray[a] = heapArray[b];
        heapArray[b] = temp;
    }
}

上面的代码示例中,我们创建了一个名为MaxHeap的类,它有以下方法:

  • insert(int value):向堆中插入一个值,保持堆继续满足最大堆的要求。
  • remove():移除堆中的最大值,并返回。
  • heapify(int pos):从给定位置开始重构最大堆,让堆重新满足最大堆的要求。
  • parent(int pos):返回一个节点的父节点的位置。
  • leftChild(int pos):返回一个节点的左子节点的位置。
  • rightChild(int pos):返回一个节点的右子节点的位置。
  • isLeaf(int pos):检查一个节点是否叶子节点。

示例说明

示例一

以下是一个简单的使用示例:

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

        System.out.print("Heap: ");
        for(int i=0; i<9; i++) {
            System.out.print(maxHeap.remove()+ " ");
        }
    }
}

输出结果如下:

Heap: 84 22 19 17 10 9 6 5 3

在示例中,我们先实例化一个MaxHeap对象,然后向其中插入了一些数字,然后从堆中移除最大值,并打印出堆成员的剩余值。

示例二

以下是一个更高级的示例,它使用了自定义类作为堆的元素:

public class StudentHeap {
    private Student[] heapArray;
    private int size;

    public StudentHeap(int maxSize) {
        heapArray = new Student[maxSize];
        size = 0;
    }

    public void insert(Student s){
        if(size == heapArray.length) {
            throw new ArrayIndexOutOfBoundsException("Heap is full.");
        }

        heapArray[size] = s;
        int current = size;
        while(heapArray[current].compareTo(heapArray[parent(current)]) > 0){
            swap(current,parent(current));
            current = parent(current);
        }
        size++;
    }

    public Student remove(){
        if(size == 0){
            throw new NullPointerException("Heap is empty.");
        }

        Student root = heapArray[0];
        heapArray[0] = heapArray[size - 1];
        size--;
        heapify(0);

        return root;
    }

    private void heapify(int pos){
        if(isLeaf(pos)){
            return;
        }

        int leftChild = leftChild(pos);
        int rightChild = rightChild(pos);
        int max = pos;
        if(leftChild < size && heapArray[leftChild].compareTo(heapArray[max]) > 0){
            max = leftChild;
        }
        if(rightChild < size && heapArray[rightChild].compareTo(heapArray[max]) > 0){
            max = rightChild;
        }
        if(max != pos){
            swap(pos,max);
            heapify(max);
        }
    }

    private int parent(int pos) {
        return (pos - 1) / 2;
    }

    private int leftChild(int pos) {
        return 2 * pos + 1;
    }

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

    private boolean isLeaf(int pos) {
        return pos >= (size / 2) && pos < size;
    }

    private void swap(int a, int b) {
        Student temp = heapArray[a];
        heapArray[a] = heapArray[b];
        heapArray[b] = temp;
    }
}

class Student implements Comparable<Student>{
    private String name;
    private int age;
    private double grade;

    public Student(String name, int age, double grade) {
        this.name = name;
        this.age = age;
        this.grade = grade;
    }

    @Override
    public int compareTo(Student s) {
        return Double.compare(this.grade, s.grade);
    }

    @Override
    public String toString() {
        return name + "(age=" + age + ", grade=" + grade + ")";
    }
}

public class Main {
    public static void main(String[] args) {
        StudentHeap studentHeap = new StudentHeap(10);
        studentHeap.insert(new Student("Alice", 20, 95.0));
        studentHeap.insert(new Student("Bob", 21, 88.5));
        studentHeap.insert(new Student("Charlie", 19, 90.3));
        studentHeap.insert(new Student("David", 22, 92.6));

        System.out.print("Heap: ");
        for(int i=0; i<4; i++) {
            System.out.print(studentHeap.remove() + " ");
        }
    }
}

输出结果如下:

Heap: Alice(age=20, grade=95.0) David(age=22, grade=92.6) Charlie(age=19, grade=90.3) Bob(age=21, grade=88.5) 

在示例中,我们创建了一个Student类,用于存储学生信息。然后创建了一个名为StudentHeap的最大堆对象,并向其中插入了四个Student对象。由于Student类实现了Comparable<Student>接口,所以我们可以直接通过次数变量grade来比较不同的学生。最后,我们从堆中移除最大值,并打印出剩余的值。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java语言实现最大堆代码示例 - Python技术站

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

相关文章

  • 通过实践了解如何处理Java异常

    处理 Java 异常的攻略如下: 异常概述 Java 异常能够帮助我们处理程序运行时的错误或者问题,同时在出现异常情况下,也可以给用户展示错误信息,方便问题的排查与解决。Java 中的异常主要分为两类:已检查异常(Checked Exception)和运行时异常(Runtime Exception)。已检查异常通常是在方法声明中显式申明的,需要在方法调用处进…

    Java 2023年5月26日
    00
  • java以json格式向后台服务器接口发送请求的实例

    下面我来详细讲解「Java以JSON格式向后台服务器接口发送请求的实例」: 1.什么是JSON JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。在前后端通信的接口中,JSON格式被广泛应用。它具有易读性好、可解析性强等特点,通常使用键值对表示数据。键值对之间使用冒号(:)分割,不同的键值对之间使用逗号(,)分割,键…

    Java 2023年5月26日
    00
  • java 实现反射 json动态转实体类–fastjson

    Java中的反射是一种可以在运行时动态获取类的信息的机制。而fastjson则是一种常用的Java JSON 库,它支持将JSON字符串快速地转换为Java对象,以及将Java对象快速地序列化为JSON字符串。下面将详细介绍如何使用Java反射结合fastjson实现JSON字符串到Java对象的转换。 1. 添加依赖接口 我们需要在项目中添加fastjso…

    Java 2023年5月26日
    00
  • MyBatis实践之DAO与Mapper

    MyBatis实践之DAO与Mapper攻略 MyBatis是一个流行的ORM框架。它使用XML文件或注释映射Java对象到数据库,并提供了一组强大的特性来处理数据库操作。本文将详细讲解MyBatis中的DAO和Mapper,并提供两个示例以演示它们的使用。 DAO DAO(Data Access Object)是一种数据访问设计模式,它将数据访问从业务逻辑…

    Java 2023年5月20日
    00
  • 详解.NET主流的几款重量级 ORM框架

    详解.NET主流的几款重量级 ORM 框架 在 .NET 开发领域,ORM 框架是不可缺少的一部分。ORM 框架能够将程序和数据库之间的交互转化为对象之间的交互,从而简化了开发过程,提高了代码的可维护性和可读性。 下面将详细讲解.NET 主流的几款 ORM 框架和其使用方法。 Entity Framework Entity Framework 是微软开发的 …

    Java 2023年5月20日
    00
  • SpringBoot应用的打包和发布实现

    打包和发布Spring Boot应用可以使用多种方法,下面是一些常见的方法: 方法一:使用Maven插件打包并上传到服务器 步骤一:使用Maven构建Spring Boot应用 在pom.xml文件中添加以下依赖: <!– 引入Spring Boot的pom依赖 –> <parent> <groupId>org.spr…

    Java 2023年5月19日
    00
  • JavaScript入门之对象与JSON详解

    JavaScript入门之对象与JSON详解 1. 什么是对象 对象是一种复合值,将很多值(原始类型或另一个对象)集合在一起,可以方便地组织和管理这些值。 2. 对象的创建 2.1 对象字面量创建对象 对象字面量是表示对象的最简洁方式之一,由一堆用逗号隔开的 名/值 对 组成,逗号后面的属性值可以是任意合法的JavaScript表达式。 示例1: let s…

    Java 2023年5月26日
    00
  • jsp 常用标签的使用

    下面是关于“JSP 常用标签的使用”的完整攻略: 1. JSP 常用标签简介 JSP 常用标签可以分为以下几类: 基本标签:以下标签是使用最为频繁的 JSP 标签,它们能够帮助实现基本的输出、判断、循环等功能。 <%@ page %>:用于页面的指令,可以设置页面的属性等。 <%= %>:输出表达式,可以输出 JSP 中的表达式的值。…

    Java 2023年6月15日
    00
合作推广
合作推广
分享本页
返回顶部