前言:队列是一种先进先出的数据结构,但是某时候有一些数据有优先级,比如打游戏时候突然来个电话。在这种情况下,数据结构应该提供两个最基本的操作,一个是返回最高优先级对象,一个是添加新的对象。这种数据结构就是优先级队列(Priority Queue)。
1:堆概念
官方:如果有一个关键码的集合K = {k0,k1, k2,…,kn-1},把它的所有元素按完全二叉树的顺序存储方式存储 在一个一维数组中,并满足:Ki <= K2i+1 且 Ki<= K2i+2 (Ki >= K2i+1 且 Ki >= K2i+2) i = 0,1,2…,则称为 小堆(或大堆)。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。
我自己简单认为就是把二叉树修改了一些,修改了存储方式,二叉树是一种链式存储,而堆是一种顺序存储是数组,分为了大根堆和小根堆
堆的一些特征:
1:堆是一颗完全二叉树
2:堆采用的是层序规则顺序存储结构,因为堆是一颗完全二叉树,非完全二叉树不适合顺序存储,会造成空间的浪费
2:堆的子节点的值不大于或者不小于其父亲结点的值
以小根堆为例:
一些重要的二叉树性质:
2:堆的创建(以小根堆为例)
问题:对于集合{ 27,15,19,18,28,34,65,49,25,37 }中的数据,如果将其创建成堆呢?
我自己理解画的图的和写的代码:
public class TestHeap {
public int usedSize;
public int []elem;
public TestHeap() {
this.elem = new int[10];
}
public void initElem(int[] array) {
for (int i = 0; i < array.length; i++) {
this.elem[i] = array[i];
usedSize++;
}
}
// 时间复杂度:O(N)
public void createHeap() {
//每个父亲节点
for (int parent=(usedSize-1-1)/2;parent>=0;parent--) {
sitfDown(parent,usedSize-1);//调整
}
}
时间复杂度:O(log(n))
private void sitfDown(int parent, int i) {
int child=2*parent+1;//先求出左孩子结点
while(child<=i) { //结束条件child<useSize这里传过来的是usedSize-1
if ((child+1<=i)&&