堆的定义:
堆其实就是完全二叉树的结构,在数值的表现方式上就是树的根节点大于等于(小于等于)左右子节点的值。
关于堆的详细操作有:插入和删除
插入:直接将插入的元素添加到数组的末尾,然后再自下而上的进行堆化(这里默认讲的是大顶堆),重新调整堆,使其满足大顶堆
删除:一般指的是删除堆顶元素,将数组的末尾元素移动到堆顶,然后再自上而下的调整堆,使其满足大顶堆的要求
堆排序:
1. 先将数组内的元素构建成大顶堆
2. 将堆顶元素(数组中下标为 1 的元素 )与数组末尾的元素进行交换,重新堆化,使堆满足大顶堆的特性
3. 重复步骤 2 ,直至最后一个元素
// 大顶堆
public class Heap {
private int [] a;
private int count;
private int n;
public Heap(int capacity){
a = new int [capacity + 1];
n = capacity;
count = 0;
}
// 向堆中插入一个元素
public void insert(int data){
if(count >= n) return;
count++;
a[count] = data;
int i = count;
while(i / 2 > 0 && a[i] > a[i / 2]){
swap(a, i, i / 2);
i /= 2;
}
}
// 删除堆顶元素
public void delete(){
if(count == 0) return;
a[1] = count;
count--;
heapify(a, count, 1);
}
// 自上而下的进行堆化
public void heapify(int a [], int count, int i){
while(true){
int maxPos = i;
if(i * 2 < count && a[i] < a[i * 2]) maxPos = 2 * i;
if(i * 2 + 1 < count && a[i] < a[i * 2 + 1]) maxPos = 2 * i + 1;
if(maxPos == i) break;
swap(a, i, maxPos);
i = maxPos;
}
}
// 在数组中从后向前,构建大顶堆
public void buildHeap(int [] a, int n){
for(int i = n / 2; i >= 1; i--){
heapify(a, n, i);
}
}
// 堆排序,从小到大排序
public void sort(int [] a, int n){
buildHeap(a, n);
int k = n;
while(k > 1){
swap(a, 1, k);
k--;
heapify(a, k, 1);
}
}
// 交换数组内的两个元素
public void swap(int [] a, int i, int j){
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}