数据结构学习记录——什么是堆(优先队列、堆的概念、最大堆最小堆、优先队列的完全二叉树表示、堆的特性、堆的抽象数据类型描述)

简介: 数据结构学习记录——什么是堆(优先队列、堆的概念、最大堆最小堆、优先队列的完全二叉树表示、堆的特性、堆的抽象数据类型描述)

优先队列

优先队列(Priority Queue):

特殊的“队列”,取出元素的顺序是依照元素的优先权(关键字)大小,而不是元素进入队列的先后顺序。

若采用数组或链表实现优先队列

数组

插入操作——元素总是插入尾部        ~

删除操作——查找最大(或最小) 关键字        ~

                       从数组中删去需要移动的元素        ~

插入操作的时间复杂度为O(1),只需要将元素插入到数组的末尾即可。


但是删除操作的时间复杂度为O(n),因为需要找到优先级最高的元素,这可能需要遍历整个数组。

链表

插入操作——元素总是插入链表的头部        ~

删除操作——查找最大(或最小)关键字        ~

                       删去结点        ~

插入操作的时间复杂度为O(1),同样只需要在链表末尾插入一个节点即可。

而删除操作时,查找最大(或最小)关键字可能需要遍历整个链表再进行删除,所以时间复杂度为O(n)。

有序数组

插入操作——找到合适的位置        ~

                       移动元素并插入        ~

删除操作——删去最后一个元素        ~

采用有序数组使得优先队列在删除时方便了很多,但是在插入时却同样会变得十分麻烦,要找到合适的位置进行插入,再移动元素。

有序链表

插入操作——找到合适的位置        ~

                       插入元素        ~

删除操作——删除首元素或最后元素        ~

除了在插入时不用移动元素,有序链表与有序数组基本相同。

总结

给出的这四个方案中,总有存在不足。要么是提高了插入操作的效率,删除操作的效率十分低;要么是提高了删除操作的效率,而插入操作的效率十分低。

所以我们要想用一种新的方式来存储:二叉树

若采用二叉搜索树来实现优先队列

通过前面的学习,我们了解到:

在二叉搜索树中,每个结点都有一个键值,且左子树中的所有结点的键值小于该结点的键值,右子树中的所有结点的键值大于该结点的键值。


因此,可以将优先级作为键值,将元素作为结点存储在二叉搜索树中。


在插入元素时,根据元素的优先级将其插入到正确的位置。


在删除元素时,可以删除具有最高优先级的元素,即最大元素或最小元素。


但是,


当我们连续删除最大值或者连续删除最小值时,这棵二叉搜索树会变得越来越斜,二叉搜索树的插入和删除操作的时间复杂度可能会退化为O(n)。达不到我们要求的高效率了。


所以,我们要思考:采用二叉树的结构来实现这个优先队列的话,要更应该关注插入操作还是删除操作?

最大堆

很显然,采用二叉树结构来实现优先队列时,更应该关注的是删除操作,连续不断地删除二叉搜索树的最值的话,会使得其越来越不平衡。

那么就不删除左右子树,改为删除根结点。

我们把最大值放在根结点上,要删除最大值时直接删除根结点即可。

故而有一个原则:任何一个结点,都是以它为根的这个子树的最大值。

那么满足这个原则的结构,我们称它为最大堆。

为了是这个二叉树能够平衡一点,我们在实现时,最好的方法应该是使用完全二叉树

我们引出堆的概念:

堆的概念

堆是一种特殊的树形结构,其中每个结点都有一个值,通常称为“键值”,并且每个结点的键值都满足一定的条件

其中具有最高(或最低)优先级的元素总是位于堆的根结点

堆可以分为最大堆和最小堆

最大堆中父结点的键值总是大于或等于任何一个子结点的键值,

而最小堆中父结点的键值总是小于或等于任何一个子结点的键值。

而堆的一个特点就是用完全二叉树来存储。

优先队列的完全二叉树表示

堆的两个特性

结构性

用数组表示的完全二叉树。

有序性

任一结点的关键字是其子树所有结点的最大值(或最小值)

  • 最大堆(MaxHeap)”,也称“大顶堆”:最大值
  • 最小堆(MinHeap)”,也称“小顶堆”:最小值

【例】最大堆和最小堆

【例】不是堆

堆的抽象数据类型描述

类型名称:最大堆(MaxHeap)

数据对象集:完全二叉树,每个结点的元素值不小于其自子结点的元素值

操作集:最大堆HMaxHeap,元素itemElementType,主要操作有:


  • MaxHeap Create(int MaxSize):创建一个空的最大堆。
  • Boolean IsFull(MaxHeap H):判断最大堆H是否已满。
  • Insert(MaxHeap H,ElementType item):将元素item插入最大堆H。
  • Boolean IsEmpty(MaxHeap H):判断最大堆H是否为空。
  • ElementType DeleteMax(MaxHeap H):返回H中最大元素(高优先级)。

 


end



目录
相关文章
|
3天前
|
算法 C++
数据结构与算法===优先队列
数据结构与算法===优先队列
数据结构与算法===优先队列
|
2天前
|
算法 Java 机器人
Java数据结构与算法:最大堆
Java数据结构与算法:最大堆
|
2天前
|
算法 Java 机器人
Java数据结构与算法:最小堆
Java数据结构与算法:最小堆
|
6天前
|
搜索推荐 算法
【排序】数据结构——排序算法概念及代码详解(插入、冒泡、快速、希尔)
【排序】数据结构——排序算法概念及代码详解(插入、冒泡、快速、希尔)
|
6天前
|
存储 算法
【树】数据结构——树和二叉树的概念&笔记
【树】数据结构——树和二叉树的概念&笔记
|
12天前
|
存储
数据结构初阶 堆(一)
数据结构初阶 堆(一)
10 1
|
17天前
|
存储 算法 测试技术
数据结构学习记录——树习题-Complete Binary Search Tree(题目描述、输入输出示例、数据结构的选择、核心算法、计算左子树的规模)
数据结构学习记录——树习题-Complete Binary Search Tree(题目描述、输入输出示例、数据结构的选择、核心算法、计算左子树的规模)
16 1
|
17天前
|
测试技术 C语言
数据结构学习记录——树习题—Tree Traversals Again(题目描述、输入输出示例、解题思路、解题方法C语言、解析)
数据结构学习记录——树习题—Tree Traversals Again(题目描述、输入输出示例、解题思路、解题方法C语言、解析)
14 1
|
3天前
|
Python
数据结构===堆
数据结构===堆
|
6天前
|
存储 算法
【二叉树】数据结构——BST二叉树基本概念及算法设计(插入、删除、遍历操作)
【二叉树】数据结构——BST二叉树基本概念及算法设计(插入、删除、遍历操作)