Java如何利用完全二叉树创建大根堆和小根堆

发布时间:2022-08-09 09:41:50 作者:iii
来源:亿速云 阅读:198

Java如何利用完全二叉树创建大根堆和小根堆

引言

在计算机科学中,堆(Heap)是一种特殊的树形数据结构,通常用于实现优先队列。堆可以分为大根堆(Max Heap)和小根堆(Min Heap)。大根堆的每个节点的值都大于或等于其子节点的值,而小根堆的每个节点的值都小于或等于其子节点的值。本文将详细介绍如何在Java中利用完全二叉树创建大根堆和小根堆。

完全二叉树简介

完全二叉树(Complete Binary Tree)是一种特殊的二叉树,其中除了最后一层,其他层的节点都是满的,并且最后一层的节点都尽可能地集中在左侧。完全二叉树的一个重要特性是,它可以用数组来表示,而不需要使用指针或引用。

完全二叉树的数组表示

假设我们有一个完全二叉树,其节点按层次遍历的顺序存储在数组arr中。对于数组中的任意一个元素arr[i],其左子节点为arr[2*i+1],右子节点为arr[2*i+2],父节点为arr[(i-1)/2]

大根堆的创建

大根堆的创建过程通常称为“堆化”(Heapify)。堆化的目的是将数组中的元素重新排列,使其满足大根堆的性质。

堆化过程

  1. 从最后一个非叶子节点开始:最后一个非叶子节点的索引为(n/2)-1,其中n是数组的长度。
  2. 比较节点与其子节点:对于每个非叶子节点,比较其值与左右子节点的值。如果当前节点的值小于其子节点的值,则交换它们。
  3. 递归堆化:交换后,继续对交换后的子节点进行堆化,直到整个数组满足大根堆的性质。

Java代码实现

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

    public MaxHeap(int[] arr) {
        this.heap = arr;
        this.size = arr.length;
        buildMaxHeap();
    }

    private void buildMaxHeap() {
        for (int i = (size / 2) - 1; i >= 0; i--) {
            heapify(i);
        }
    }

    private void heapify(int i) {
        int largest = i;
        int left = 2 * i + 1;
        int right = 2 * i + 2;

        if (left < size && heap[left] > heap[largest]) {
            largest = left;
        }

        if (right < size && heap[right] > heap[largest]) {
            largest = right;
        }

        if (largest != i) {
            swap(i, largest);
            heapify(largest);
        }
    }

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

    public void printHeap() {
        for (int i = 0; i < size; i++) {
            System.out.print(heap[i] + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        int[] arr = {4, 10, 3, 5, 1};
        MaxHeap maxHeap = new MaxHeap(arr);
        maxHeap.printHeap(); // 输出: 10 5 3 4 1
    }
}

代码解析

小根堆的创建

小根堆的创建过程与大根堆类似,只是比较的方向相反。

堆化过程

  1. 从最后一个非叶子节点开始:最后一个非叶子节点的索引为(n/2)-1,其中n是数组的长度。
  2. 比较节点与其子节点:对于每个非叶子节点,比较其值与左右子节点的值。如果当前节点的值大于其子节点的值,则交换它们。
  3. 递归堆化:交换后,继续对交换后的子节点进行堆化,直到整个数组满足小根堆的性质。

Java代码实现

public class MinHeap {
    private int[] heap;
    private int size;

    public MinHeap(int[] arr) {
        this.heap = arr;
        this.size = arr.length;
        buildMinHeap();
    }

    private void buildMinHeap() {
        for (int i = (size / 2) - 1; i >= 0; i--) {
            heapify(i);
        }
    }

    private void heapify(int i) {
        int smallest = i;
        int left = 2 * i + 1;
        int right = 2 * i + 2;

        if (left < size && heap[left] < heap[smallest]) {
            smallest = left;
        }

        if (right < size && heap[right] < heap[smallest]) {
            smallest = right;
        }

        if (smallest != i) {
            swap(i, smallest);
            heapify(smallest);
        }
    }

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

    public void printHeap() {
        for (int i = 0; i < size; i++) {
            System.out.print(heap[i] + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        int[] arr = {4, 10, 3, 5, 1};
        MinHeap minHeap = new MinHeap(arr);
        minHeap.printHeap(); // 输出: 1 4 3 5 10
    }
}

代码解析

堆的应用

堆在计算机科学中有广泛的应用,尤其是在优先队列、堆排序、图算法(如Dijkstra算法)等领域。

优先队列

优先队列是一种特殊的队列,其中每个元素都有一个优先级。优先队列通常使用堆来实现,因为堆可以高效地获取和删除最高(或最低)优先级的元素。

堆排序

堆排序是一种基于堆的排序算法。它的基本思想是将待排序的数组构建成一个堆,然后依次将堆顶元素(最大或最小)取出,放到数组的末尾,最终得到一个有序数组。

图算法

在图算法中,堆常用于实现Dijkstra算法,用于求解单源最短路径问题。Dijkstra算法需要频繁地从优先队列中取出当前距离最小的节点,堆可以高效地支持这一操作。

总结

本文详细介绍了如何在Java中利用完全二叉树创建大根堆和小根堆。通过堆化过程,我们可以将数组中的元素重新排列,使其满足堆的性质。堆在计算机科学中有广泛的应用,尤其是在优先队列、堆排序和图算法中。掌握堆的创建和操作,对于理解和实现这些算法具有重要意义。

参考文献


通过本文的学习,读者应该能够理解如何在Java中利用完全二叉树创建大根堆和小根堆,并掌握堆的基本操作和应用场景。希望本文能为读者在数据结构和算法的学习中提供帮助。

推荐阅读:
  1. java利用构建器来创建实例
  2. 怎么在Java中利用Callable和Future创建线程

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java

上一篇:vue脚手架交互式命令行和图形化界面如何安装

下一篇:python接口自动化如何使用requests库发送http请求

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》