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日

相关文章

  • Spring Security 强制退出指定用户的方法

    下面是关于“Spring Security 强制退出指定用户的方法”的攻略: 一、背景知识 首先需要了解一下Spring Security的基础知识。 Spring Security是一个基于Spring框架的安全框架,主要用于保护Web应用程序中的安全性。它提供了诸如身份验证、授权、攻击防护等安全功能,可以轻松添加到现有的Spring应用程序中。 在Spr…

    Java 2023年5月20日
    00
  • 什么是线程安全问题?

    以下是关于什么是线程安全问题的完整使用攻略: 什么是线程安全问题? 线程安全问题是指在多线程环境下,对共享资源的访问可能会出现数据不一致或者数据污染的问题。在多线程环境下,如果多个线程同时访问同一个共享资源,那么就有可能出现数据一致的问题,这就是线程全问题。 为了保证线程安全需要采取一些措施,比如使用同步机制、使用线程安全的数据结构。 1. 同步机制 同步机…

    Java 2023年5月12日
    00
  • JDBC Template基本使用方法详解

    JDBC Template基本使用方法详解 JDBC Template简介 JDBC(Java Database Connectivity)是一个Java语言访问数据库的接口,JDBC Template是使用JDBC进行数据库操作的常用工具类,该类能够自动化处理资源申请、资源释放等常规流程,并提供了诸如CRUD、批量操作、分页查询等常用数据库操作方法,使用J…

    Java 2023年6月16日
    00
  • Java实现深度优先搜索(DFS)和广度优先搜索(BFS)算法

    Java实现深度优先搜索(DFS)和广度优先搜索(BFS)算法 深度优先搜索(DFS)和广度优先搜索(BFS)算法是常用的遍历和搜索算法,具有很高的实用价值。在Java中,我们可以通过使用递归函数和队列这两种数据结构来实现这两种算法。下面将对这两种算法进行详细的讲解。 深度优先搜索(DFS) 深度优先搜索(DFS)是一种常用的遍历算法,其思想就是从起点开始,…

    Java 2023年5月19日
    00
  • 10中java常见字符串操作实例

    以下是“10种Java常见字符串操作实例”的完整攻略: 简介 字符串是Java中最常用的数据类型之一,几乎所有的Java程序都会涉及字符串的处理。本文主要介绍Java中常见的字符串操作方法。 10种Java常见字符串操作实例 1. 字符串的比较 比较两个字符串是否相等,可以使用equals()方法。 示例1: String str1 = "Hell…

    Java 2023年5月26日
    00
  • 如何保持Java编程风格一致?

    以下是详细讲解“如何保持Java编程风格一致?”的完整使用攻略。 1. 了解Java编程规范 在保持Java编程风格一致的过程中,了解Java编程规范是非常必要的。Java编程规范是指一系列的编程规则和规范,主要包括: 包名:包名应该是小写的,多个单词之间使用下划线分隔。 类名:类名应该是首字母大写的驼峰命名法。 方法名:方法名应该是首字母小写的驼峰命名法。…

    Java 2023年5月11日
    00
  • Spring Boot与Spring MVC Spring对比及核心概念

    下面是关于“Spring Boot与Spring MVC Spring对比及核心概念”的详细攻略。 一、Spring Boot与Spring MVC Spring对比 1. Spring Spring框架是一个Java开发的应用程序框架,它为Java平台提供了综合的编程和配置模型。Spring框架是面向切面编程(AOP)的优秀实现,它的核心技术包括依赖注入(…

    Java 2023年5月15日
    00
  • Java实现获得MySQL数据库中所有表的记录总数可行方法

    下面就来详细讲解“Java实现获得MySQL数据库中所有表的记录总数可行方法”的完整攻略。 1. 方案介绍 在 Java 中,我们可以使用 JDBC(Java Database Connectivity)API 来访问关系型数据库,其中包括 MySQL 数据库。我们可以通过执行 SQL 语句获取 MySQL 数据库中所有表的记录总数,主要有以下两种方法: 1…

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