数据结构(9)树形结构——大顶堆、小顶堆

简介: 9.1.概述概念:根节点是自己所在子树中的最值的完全二叉树。根节点是所在子树的最大值,称为大顶堆。根节点是所在子树的最小值,称为小顶堆。堆的任何子树的根节点到子树上的任意节点,路径上的节点都是有序的,大顶堆为降序,小顶堆为升序。此处展示一个大顶堆:

9.1.概述

概念:

根节点是自己所在子树中的最值完全二叉树。

根节点是所在子树的最大值,称为大顶堆

根节点是所在子树的最小值,称为小顶堆

堆的任何子树的根节点到子树上的任意节点,路径上的节点都是有序的,大顶堆为降序,小顶堆为升序。

此处展示一个大顶堆:

bcc17e16db1c47df8395ab5fb9c71d7f.png

作用:

堆一般用来在大量数据中找到前N大或者前N小的数据。

存储:

一般用数组来存储堆,首先因为堆一般是从空树开始建立的,不论如何操作其一定会是一颗完全二叉树,不存在大量非叶子结点没有左右孩子的情况,所以用数组来表示不会造成内存浪费。其次堆的删除操作需要从叶节点反向向根结点方向遍历,链表结构不太好支持这种反向遍历。

9.2.操作

9.2.1.插入

堆的插入采用尾插法,新入堆的节点挂在最后一个叶节点上,然后往上浮(交换位置)。

假设已有一颗树,是按照44、25、31、18、10的插入顺序建树的。

假设插入的是20:

1e670627a2134652aa3ec60918e4fb0d.png

假设插入的是35:

b5ba353e7a6c4ad083cf25cc6a1d40bc.png

9.2.2.删除

堆的删除操作,从叶子结点开始删除的话,直接删除即可,不会有任何影响,只有在删除非叶子结点时才要考虑进行结点间的调整,保持堆是大顶堆或者小顶堆。

堆在使用时每次弹出的都是堆顶的数据,因此删除操作都是针对堆顶元素的,此处以大顶堆的删除操作为例:

用最末尾的叶节点替换根节点,然后新的根节点与左右孩子比较是否为最大值,若不为最大值,则与参与比较的三个节点中的最大值互换位置,然后递归以上过程,出口为到达叶节点或者到达合适位置。

9.2.3.代码实现

package linearStructure.tree.heap;
import java.util.ArrayList;
import java.util.List;
public class MaxTopHeap {
    //存储堆的数组
    private int[] heap;
    //堆的最大存储容量
    private int maxSize;
    //当前堆的存储数量
    private int heapSize;
    public MaxTopHeap(int maxSize) {
        this.heap = new int[maxSize];
        this.maxSize = maxSize;
        this.heapSize = 0;
    }
    // 判断是否为空的方法
    public boolean isEmpty() {
        return heapSize == 0;
    }
    // 判断是否填满
    public boolean isFull() {
        return heapSize == maxSize;
    }
    // 获取堆顶的值
    public int peek() throws Exception {
        if (heapSize == 0) {
            throw new Exception("heap is empty");
        }
        return heap[0];
    }
    // 往堆中添加值
    public void insert (int value) throws Exception {
        if (heapSize == maxSize) {
            throw new Exception("head is full");
        }
        heap[heapSize] = value;
        heapSize++;
        buildMaxHeap(heap);
    }
    // 删除堆顶值
    public int poll() throws Exception {
        if (heapSize == 0) {
            throw new Exception("heap is empty");
        }
        int ans = heap[0];
        swap(heap,0,--heapSize);
        buildMaxHeap(heap);
        return ans;
    }
    // 建大顶堆
    private int[] buildMaxHeap(int[] array) {
        for (int i = (heapSize-2)/2; i >= 0; i--) {
            adjustDownToUp(array,i,heapSize);
        }
        return array;
    }
    private void adjustDownToUp(int[] array, int index, int length) {
        int temp = array[index];
        for (int i = 2*index+1; i < length; i = 2*i+1) {
            if (i < length-1 && array[i] < array[i+1]) {
                i++;
            }
            if (temp >= array[i]) {
                break;
            } else {
                array[index] = array[i];
                index = i;
            }
        }
        array[index] = temp;
    }
    // 交换元素值
    private void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
    // 获取所有元素
    public List<Integer> getAllElements() {
        List<Integer> ans = new ArrayList<>();
        for (int i = 0; i < heapSize; i++) {
            ans.add(heap[i]);
        }
        return ans;
    }
}


目录
相关文章
|
4月前
|
存储 算法 Java
散列表的数据结构以及对象在JVM堆中的存储过程
本文介绍了散列表的基本概念及其在JVM中的应用,详细讲解了散列表的结构、对象存储过程、Hashtable的扩容机制及与HashMap的区别。通过实例和图解,帮助读者理解散列表的工作原理和优化策略。
65 1
散列表的数据结构以及对象在JVM堆中的存储过程
|
4月前
|
存储 搜索推荐 算法
【数据结构】树型结构详解 + 堆的实现(c语言)(附源码)
本文介绍了树和二叉树的基本概念及结构,重点讲解了堆这一重要的数据结构。堆是一种特殊的完全二叉树,常用于实现优先队列和高效的排序算法(如堆排序)。文章详细描述了堆的性质、存储方式及其实现方法,包括插入、删除和取堆顶数据等操作的具体实现。通过这些内容,读者可以全面了解堆的原理和应用。
165 16
|
6月前
|
存储 Java
【数据结构】优先级队列(堆)从实现到应用详解
本文介绍了优先级队列的概念及其底层数据结构——堆。优先级队列根据元素的优先级而非插入顺序进行出队操作。JDK1.8中的`PriorityQueue`使用堆实现,堆分为大根堆和小根堆。大根堆中每个节点的值都不小于其子节点的值,小根堆则相反。文章详细讲解了如何通过数组模拟实现堆,并提供了创建、插入、删除以及获取堆顶元素的具体步骤。此外,还介绍了堆排序及解决Top K问题的应用,并展示了Java中`PriorityQueue`的基本用法和注意事项。
88 5
【数据结构】优先级队列(堆)从实现到应用详解
|
5月前
|
存储 JavaScript 前端开发
为什么基础数据类型存放在栈中,而引用数据类型存放在堆中?
为什么基础数据类型存放在栈中,而引用数据类型存放在堆中?
190 1
|
5月前
|
存储 算法 调度
数据结构--二叉树的顺序实现(堆实现)
数据结构--二叉树的顺序实现(堆实现)
|
5月前
|
存储 算法 分布式数据库
【初阶数据结构】理解堆的特性与应用:深入探索完全二叉树的独特魅力
【初阶数据结构】理解堆的特性与应用:深入探索完全二叉树的独特魅力
110 1
|
5月前
|
存储 算法
探索数据结构:分支的世界之二叉树与堆
探索数据结构:分支的世界之二叉树与堆
|
5月前
|
存储 算法 Java
【用Java学习数据结构系列】用堆实现优先级队列
【用Java学习数据结构系列】用堆实现优先级队列
59 0
|
5月前
|
存储 算法
【数据结构】二叉树——顺序结构——堆及其实现
【数据结构】二叉树——顺序结构——堆及其实现
|
5月前
【数据结构】大根堆和小根堆
【数据结构】大根堆和小根堆
120 0