堆数据结构详解(定义作用及实现原理)

堆数据结构详解(定义作用及实现原理)-mikechen

堆数据结构定义

堆是一个完全二叉树,通常使用数组来表示,其中树中的每个节点都具有一个值。

如下图所示:

堆数据结构详解(定义作用及实现原理)-mikechen

这意味着树中的所有层次除了最底层都是完全填充的,而且最底层的节点从左到右填充。

 

堆数据结构作用

堆数据结构主要用于以下几方面:

1.实现优先队列

堆可用于实现高效的优先队列,其中元素具有优先级,并且具有最高或最低优先级的元素可以快速访问。

2.堆排序

堆排序是一种高效的排序算法,利用堆来对元素进行排序。

3.图算法

在图算法中,堆经常用于Dijkstra算法和Prim算法等,以找到最短路径和最小生成树。

4.内存分配

堆内存通常用于动态分配和管理对象,如Java中的对象分配。

5.任务调度

在操作系统和并发编程中,堆可用于实现任务调度和线程管理。

 

堆数据结构实现

堆有两种主要类型:最大堆和最小堆。

最大堆(Max Heap)

在最大堆中,父节点的值始终大于,或等于其子节点的值。

如下图所示:

堆数据结构详解(定义作用及实现原理)-mikechen

最大堆中的元素遵循最大堆属性,这意味着父节点的键始终大于两个子节点的键。

要构建最大堆:

  • 在堆的开头(根)创建一个新节点,为其指定一个值。
  • 将子节点的值,与父节点的值进行比较。
  • 如果父节点的值,小于任一子节点的值(向左或向右),则交换节点。
  • 重复此操作,直到最大元素位于根父节点,此时可以说堆属性成立。

最大堆通常用于实现优先队列,其中具有最高优先级的元素位于堆的顶部。

最小堆(Min Heap)

在最小堆中,父节点的值,始终小于或等于其子节点的值。

直观上,我们可以说最小堆中的元素遵循最小堆属性,因为这与最大堆相反。

最小堆通常用于实现优先队列,其中具有最低优先级的元素位于堆的顶部。

堆的实现

堆通常使用数组来表示,其中树的节点按特定顺序存储在数组中。

堆的根节点存储在数组的第一个元素(索引为0或1,具体取决于实现)。

对于节点i,其左子节点存储在索引2i+1,右子节点存储在索引2i+2。

堆中的元素必须满足堆的性质,即最大堆或最小堆。

在实现堆时,需要提供一组操作,如:插入、删除、上浮和下沉操作,以确保堆的性质得以维护。

 

堆的基本操作

插入(Insertion)

将新元素插入堆,并确保堆的性质得以保持。通常是将新元素添加到数组的末尾,然后进行一系列”上浮”操作。

删除最大/最小元素(Extract Max/Min)

从堆中移除根节点(最大堆中为最大元素,最小堆中为最小元素),然后通过将最后一个元素移到根位置,进行一系列”下沉”操作,以维护堆的性质。

 

堆数据结构使用

在Java中,你可以使用内置的PriorityQueue类来轻松创建堆。

import java.util.PriorityQueue;

// 创建最小堆
PriorityQueue<Integer> minHeap = new PriorityQueue<>();

// 插入元素
minHeap.offer(5);
minHeap.offer(2);
minHeap.offer(8);

// 获取最小值
int min = minHeap.poll(); // 最小值是2

// 创建最大堆
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());

// 插入元素
maxHeap.offer(5);
maxHeap.offer(2);
maxHeap.offer(8);

// 获取最大值
int max = maxHeap.poll(); // 最大值是8

堆的实现原理在算法和数据结构中非常重要,它可以用于高效地解决各种问题,如优先队列、堆排序、图算法和任务调度等。

 

堆数据结构总结

堆是一种高效的数据结构,用于处理具有优先级的数据,同时也用于解决一些基本的算法问题。

堆排序是一种稳定的排序算法,时间复杂度为O(n log n),在某些情况下,堆可以在实际应用中发挥巨大的作用。

mikechen

mikechen睿哥,10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。

关注「mikechen」公众号,获取更多技术干货!

后台回复架构即可获取《阿里架构师进阶专题全部合集》,后台回复面试即可获取《史上最全阿里Java面试题总结

评论交流
    说说你的看法