定义
二叉堆是一个数组,可以被看做一个近似的完全二叉树。
性质:
- 含有n个元素的堆的高度是lgn。
- 在最大堆中,最大元素该子树的根上;在最小堆中,最小元素在该子树的根上。
建堆,向下调整堆,向上调整堆
- 建堆
可以使用自底向上的方法利用过程maxHeapify(向下调整堆)把数组A[1-n]转换为堆。
伪代码
- 向下调整堆maxHeapify
伪代码
算法描述
3.向上调整堆
代码
//向上调整堆
private void adjustUp(int a[],int index){
int parent = index/2;
while(index>0 && a[parent] < a[index]) {
int t = a[parent];
a[parent] = a[index];
a[index] = t;
index = parent;
parent = parent/2;
}
}
向上调整的操作过程中,当前元素会不断地与其父节点进行比较,如果当前元素的关键字较大,则当前元素与其父节点进行交换。这一过程会不断地重复,直到当前元素的关键字小于其父节点时终止,因为此时已经重新符合了最大堆的性质。
堆排序
代码
public class MaxHeap {
//堆排序
public static void heapSort(int[] a) {
buildMaxheap(a,a.length);
for(int i = a.length-1;i>=1;i--) {
int t = a[i]; a[i] = a[0]; a[0] = t;
maxHeapify(a,0,i);
}
}
//建堆
private static void buildMaxheap(int[] a,int heapSize) {
for (int i = heapSize; i >= 0; i--) {
maxHeapify(a,i,heapSize);
}
}
//向下调整堆,选择左右子树中比当前节点大的值进行交换,并继续向下递归,直至到达树底或子树已满足堆的性质
private static void maxHeapify(int[] a,int index,int heapSize) {
int l = index*2;
int r = l+1;
int largest = index;
if(l<heapSize && a[l]>a[largest])
largest = l;
if(r<heapSize && a[r]>a[largest])
largest = r;
if(index != largest) {
int t = a[index]; a[index] = a[largest]; a[largest]=t;
maxHeapify(a,largest,heapSize);
}
}
public static void main(String[] args) {
int[] a = {4,1,3,2,16,9,10,14,8,7};
MaxHeap.heapSort(a);
for(int i=0;i<a.length;i++)
System.out.println(a[i]);
}
}
优先队列
public class PriorityQueue {
private int MAX = 100;
private int[] data = new int[MAX];
private int size = 0;
//把元素插入队列中
public boolean insert(int x) {
if(size == MAX)
return false;//队列已满
data[size] = x;
adjustUp(data,size);
size++;
return true;
}
//返回最大键字的元素
public int maximum() {
if(size == 0)
return -1;
return data[0];
}
//去掉并返回最大键值
public int extractMax() {
if(size == 0)
return -1;
int max = data[0];
data[0] = data[size-1];
size = size - 1;
adjustDown(data,0,size);
return max;
}
//将第index位的关键字增加到k
public void increaseKey(int index,int k){
if(index >=0 && index<size && data[index]<k) {
data[index] = k;
adjustUp(data,index);
}
}
//向上调整堆
private void adjustUp(int a[],int index){
int parent = index/2;
while(index>0 && a[parent] < a[index]) {
int t = a[parent];
a[parent] = a[index];
a[index] = t;
index = parent;
parent = parent/2;
}
}
//向下调整堆
private void adjustDown(int[] a,int index,int heapSize) {
int l = index*2;
int r = l+1;
int large = index;
if(l<heapSize && a[large] < a[l])
large = l;
if(r<heapSize && a[large] < a[r])
large = r;
if(index != large) {
int t = a[index]; a[index] = a[large]; a[large] = t;
adjustDown(a,large,heapSize);
}
}
}