目录
基本概念
堆是一种基本的数据结构。在这里我用数组来形容,在一个二叉堆的数组中,每一个元素都要保证大于等于另外两个特定位置的元素。同时相应的,这些元素又要大于等于另外两个相应位置的元素,整个数据结构以此类推。如果我们将整个数据结构画成树状结构,就能够清晰地看出整个结构的样子。
图片中显示的是最大堆和最小堆,两者的原理近似,这里我们讨论最大堆的实现。
当一颗二叉树的每个结点都大于等于它的两个子节点时,它被称为堆有序。相应地,在堆有序的二叉树中,每个结点都小于等于它的父节点,从任意结点往上,我们都能得到一列非递减的元素;从任意结点往下,我们都能得到一列非递增的元素。根节点就是堆有序的二叉树中的最大节点。所以说在一个堆有序的二叉树中,父节点的位置是K/2,它的两个子节点的位置是2k,2k+1。这样通过索引的变化,我们就可以在数组中得到不同的元素了。
样例代码实现
package 基于堆的优先排序;
import java.util.ArrayList;
import java.util.List;
public class MaxPQ {
private List<Integer> arr; //定义一个数组,
private int N; //定义队列中的元素个数
public MaxPQ() {
arr = new ArrayList();
arr.add(1);
N = 0;
}
public boolean isEmpty() { //方法,返回队列是否为空
return N == 0;
}
public int size() { //方法,返回队列中元素的个数
return N;
}
public void inSert(int number) { //添加方法,添加元素到结合末尾,并且使用上浮方法到指定的位置
arr.add(number);
swim(++N);
}
public int deleteMax() { //删除方法,删除最大元素并把最小的元素放到第一个,然后使用下浮方法
int max = arr.get(1);
int min = arr.get(N);
arr.set(1, min);
arr.remove(N--);
sink(1);
return max;
}
public void swim(int N) {
while(N > 1 && (arr.get(N/2) < arr.get(N))){
int max = arr.get(N);
int min = arr.get(N/2);
arr.set(N,min );
arr.set(N/2, max);
N = N/2;
}
}
public void sink(int number) {
while(number*2 <= N) {
int index = number*2;
if(index < N && (arr.get(index) < arr.get(index + 1))) {
index++;
}
if(!(arr.get(number) < arr.get(index))) {
break;
}
int max = arr.get(index);
int min = arr.get(number);
arr.set(number, max);
arr.set(index, min);
number = index;
}
}
@Override
public String toString() {
return "MaxPQ [arr=" + arr + ", N=" + N + "]";
}
}