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探索之Hibernate主键生成策略详细介绍

    Java探索之Hibernate主键生成策略详细介绍 什么是Hibernate主键生成策略 在Hibernate中,主键生成策略是用于生成实体类主键的一种机制。当我们在创建实体类并进行持久化操作时,需要确定该对象的主键。Hibernate提供了多种主键生成策略,开发者可以根据业务场景选择适合的主键生成策略。 Hibernate主键生成策略分类 Hiberna…

    Java 2023年5月19日
    00
  • 当当网的内部框架开源策略案例分享

    当当网的内部框架开源策略案例分享攻略 什么是内部框架开源? 内部框架开源是指将公司或组织内部使用的基础框架开源化,让更多的人可以使用、分享和改进这些框架。这样一来,不仅可以提高公司的技术影响力和知名度,还可以吸引更多的人才、提高研发效率,使公司在技术上更加优秀。当当网是内部框架开源的典型案例之一。 当当网内部框架开源攻略 第一步:确定框架的开源目标和范围 在…

    Java 2023年5月20日
    00
  • java Long类型转为String类型的两种方式及区别说明

    Java中,可以使用两种方式将Long类型转换为String类型,分别是: 使用String类的valueOf方法进行转换 Long l = 123L; String s = String.valueOf(l); 使用Long类的toString方法进行转换 Long l = 123L; String s = l.toString(); 这两种方式的区别在于…

    Java 2023年5月27日
    00
  • JS代码实现table数据分页效果

    下面是JS代码实现table数据分页的完整攻略。 1. 为什么需要table数据分页 当我们在网页上展示大量数据的时候,如果直接呈现所有数据,会导致页面太长,用户体验不佳,同时会严重影响页面的加载速度和用户体验。因此,通常需要使用table数据分页的方式,将数据分成多页,让用户能够快速地定位到所需要的数据。 2. 如何实现table数据分页 实现table数…

    Java 2023年6月15日
    00
  • Eclipse+Java+Swing+Mysql实现电影购票系统(详细代码)

    下面我会给出一份详细的攻略,帮助你快速了解如何通过使用Eclipse、Java、Swing和Mysql来实现电影购票系统。 准备工作 安装 JDK 和 Eclipse 下载该电影购票系统所需的Java类库和驱动程序mysql-connector-java-5.1.47-bin.jar,并在Eclipse的项目中添加这些类库 搭建Mysql数据库 设计数据库 …

    Java 2023年5月23日
    00
  • Java实现的日历功能完整示例

    下面是关于“Java实现的日历功能完整示例”的详细攻略: 1. 准备工作 在实现日历功能前,需要先导入java.util.Calendar类,它是Java中处理日期和时间的核心类,可以完成大部分日历功能的操作。 我们可以通过以下语句导入该类: import java.util.Calendar; 2. 实现日历功能 2.1 显示当前日期 首先,我们需要获取当…

    Java 2023年5月19日
    00
  • Java多线程编程中ThreadLocal类的用法及深入

    Java多线程编程中ThreadLocal类的用法及深入详解 什么是ThreadLocal类? ThreadLocal是Java中一个非常重要的线程工具类。它为每个线程提供了一个单独的副本,可以在整个线程的声明周期中使用,且该副本可以在任何时候被当前线程访问。该工具类通常用于线程安全地处理共享对象。 ThreadLocal类的用法 ThreadLocal类是…

    Java 2023年5月19日
    00
  • Java中的HashSet是什么?

    Java中的HashSet是什么? Java中的HashSet是一种基于哈希表实现的无序集合,可以存储不重复的元素。它实现了Set接口,继承自AbstractSet类。HashSet中的元素不按照特定的方式排序,而是根据元素的哈希码来存储和检索元素。 HashSet内部实现了一个HashMap,将元素作为key,value则对应一个常量Object对象。通过…

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