C++数据结构之堆(二十八)

参考博客1:数据结构:堆(Heap)https://www.jianshu.com/p/6b526aa481b1
参考博客2:图解数据结构堆的各种操作与算法,程序员必备基础数据结构https://baijiahao.baidu.com/s?id=1634972438141231356&wfr=spider&for=pc (简单介绍)
参考博客3:数据结构-堆(heap)https://blog.csdn.net/juanqinyang/article/details/51418629

在后台开发人员的面试中,有这么一个经典的题目,我们有一堆定时任务,每个任务都有执行时间,这堆定时任务还有可能会不停的增加,要求我们设计一个数据结构与算法来实现,这个题目的经典答案,就是优先队列,那么优先队列的原理是什么呢?优先队列的底层原理是一个基础数据结构,叫做堆(Heap),数据结构的堆跟内存堆栈的堆不是一回事。

我们直接开门见山,数据结构中堆(Heap)是什么东西呢?这里,通常,我们讲的堆(Heap)都是二叉堆,堆是一颗完全二叉树,如果一个堆的深度为h,那么从第一层开始有1个节点,第二层有2个节点,第三层有4个节点,直到第h-1层有2^(h-2)个节点。我们把下图这种父节点小于子节点的堆称之为小根堆,反之,父节点都大于子节点的堆称之为大根堆。

在这里插入图片描述

数据结构堆(Heap)的最大作用就是用来排序!我们以小根堆为例(以下操作均已小根堆为例),查询小根堆里面最小的元素,直接取第一个元素即可,算法时间复杂度为O(1)。我们需要注意的是,一个堆如果要删除某个元素,只支持删除最顶部的元素!在堆里面,左儿子跟右儿子大小是不确定的,这个是二叉堆跟二叉排序树的一个区别(在数据结构二叉排序树中,左儿子<本身<右儿子。后面我们再来介绍下二叉排序树)。在堆中,删除头部元素称之为Pop,那么堆里面删除一个元素的算法是什么样子的呢。我们先把最底层,最右边的元素,移到第一个元素,然后跟两个儿子比较大小,与较小的儿子交换位置因为17比65,32都小,所以把32跟17交换位置。

在这里插入图片描述

重复上面的算法,将32与23,45一起比较大小,23是三者之中最小,再次交换位置

在这里插入图片描述

重复上面的算法,将32与53进行比较,发现大小一致,不用变化

在这里插入图片描述

所以,我们可以把堆的Pop操作算法总结如下:跟最后一个元素交换,从树根开始,比较儿子节点,与最小的交换,直到没有儿子或者比儿子更小,算法复杂度为O(LogN)。在堆中,插入一个元素是什么样子的呢?我们先把元素插到堆的末尾,每次都与父亲节点进行比较,如果比父亲比它小,就跟他交换位置例如下图,我们新增一个元素22,它先跟自己的父亲节点32进行比较。

在这里插入图片描述

重复上述算法,22再与23进行比较,随后交换位置

在这里插入图片描述

最后我们又得到新的小根堆,每次插入一个算法的时间复杂度为O(LogN)

在这里插入图片描述

堆的操作就是这么简单,支持3种操作,堆顶元素,弹出堆顶元素Pop,插入新的元素Insert。算法与数据结构,需要不停地练习,才能够熟练掌握,

发布了97 篇原创文章 · 获赞 222 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_32642107/article/details/103586081