优先级队列(堆)---JDK中的优先级队列默认是最小堆的实现

1.优先级队列

1.1 概念

队列是一种先进先出(FIFO)的数据结构,但有些情况下,操作的数据可能带有优先级,一般出队列时,可能需要优先级高的元素先出队列。该中场景下,使用队列显然不合适,比如:初中那会班主任排座位时可能会让成绩好的同学先挑座位。

这种情况下,数据结构应该提供两个最基本的操作,一个是返回最高优先级对象,一个是添加新的对象。这种数据结构就是优先级队列(Priority Queue)。

优先级队列:入队一样,默认从队尾入队,出队的时候按照优先级出队

优先级相同的元素按照FIFO出队,优先级高的元素首先出队。


优先级队列的两大特点:逻辑结构,不是具体的物理结构

1.元素个数动态变化

2.按照优先级出队     优先级高的元素首先出队


优先级队列这个数据结构可以使用排序数组来替代?

但是元素是无时无刻不在动态变化,出队的那一刻要进行元素的优先级排序。无时无刻不再变化的动态数据结构。

数组排序(按照优先级排序)后输出有区别吗?

第一:优先级队列不等同于排序数组。

第二:数组排序之后元素是固定的。

2.优先级队列的模拟实现

JDK1.8中的PriorityQueue底层使用了堆这种数据结构。(优先级队列背后的数据结构---堆)

2.1 堆的概念

如果有一个关键码的集合K = {k0,k1, k2,…,kn-1},把它的所有元素按完全二叉树的顺序存储方式存储 在一 个一维数组中,并满足:Ki = K2i+1 且 Ki >= K2i+2) i = 0,1,2…,则称为小堆(或大 堆)。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。

堆的性质:元素依次从上至下,从左至右进行排列

1.堆中某个节点的值总是不大于或不小于其父节点的值;

2.堆是一棵完全二叉树,一般使用动态数组(不用存储null节点,元素都靠左排列)存储具体元素。

优先级队列(堆)---JDK中的优先级队列默认是最小堆的实现_第1张图片

 2.2 堆的存储方式

结构上:堆是一颗完全二叉树。每一层节点都靠左排列,常用数组来存储完全二叉树。

关于完全二叉树的节点编号:根据编号以及索引关系,在数组中寻找某一节点的子节点与父节点。

编号和索引保持一致,都从0开始编号,若某个节点的编号(索引)为x;

性质1.判断父节点

如何判断父节点是否存在,若存在,索引是 ==> parent(x) = (x-1) / 2

x > 0,则一定存在父节点(在二叉树中,只有根节点【根节点索引为0】没有父节点),且父节点的编号为(x-1) / 2

性质2.判断左子树节点

如何判断当前节点x还存在于左子树节点?左子树节点编号是多少?

当前完全二叉树的节点个数 <= 数组最大长度

左子树节点编号为 2x + 1 < size(当前数组中有效的元素个数)

性质3.判断右子树节点

右子树节点编号为 2x + 2 < size

你可能感兴趣的:(数据结构,数据结构)