最大堆结构
/**
* 实现 最大堆 结构
*/
public class MaxHeap {
private Integer[] data;
private int count;
private int capacity;
public MaxHeap(int capacity) {
data = new Integer[capacity+1];
count = 0;
this.capacity = capacity;
}
// 新的构造函数
public MaxHeap(Integer[] arr, int n) {
this.data = new Integer[n+1];
this.capacity = n;
for(int i=0;i<n;i++){
data[i+1] = arr[i];
}
count = n;
for(int i=count/2;i>=1;i--){// Heapify算法。将n个元素逐个插入到一个空堆中,算法复杂度是O(nlogn);heapify的过程,算法复杂度是O(n)
shiftDown(i);
}
}
int size(){
return count;
}
boolean isEmpty(){
return count == 0;
}
void insert(int item){
assert(count+1<=capacity);
data[count+1] = item;
count++;
shiftUp(data,count);
}
public int extractMax(){
assert (count>0);
Integer ret = data[1];
Tlt.exch(data,1,count);
count--;
shiftDown(1);
return ret;
}
private void shiftUp(Integer[] data,int k) {
while(k>1 && data[k/2] <data[k]){
Tlt.exch(data,k/2,k);
k/=2;
}
}
private void shiftDown(int k) {
while(2*k<=count){// 保证有子节点
int j = 2*k; // 此轮循环中,data[k]和data[j]交换
if(j+1 <= count && data[j+1]>data[j]){ // 挑出最大子节点
j +=1;
}
if(data[k]>=data[j]){
break;
}
Tlt.exch(data,k,j);
k = j;
}
}
public static void main(String[] args) {
MaxHeap heap = new MaxHeap(100);
for(int i=0;i<15;i++){
heap.insert(StdRandom.uniform(0,100));
}
while(!heap.isEmpty()){
int max = heap.extractMax();
System.out.print(max+" ");
}
}
}
堆排序
public class HeapSort {
public static void sort(Integer[] arr){
Integer n = arr.length;
MaxHeap maxHeap = new MaxHeap(n);
for(int i=0;i<n;i++){
maxHeap.insert(arr[i]);
}
for(int i=n-1;i>=0;i--){
arr[i] = maxHeap.extractMax();
}
}
public static void sort2(Integer[] arr){
Integer n = arr.length;
MaxHeap maxHeap = new MaxHeap(arr,n);
for(int i=n-1;i>=0;i--){
arr[i] = maxHeap.extractMax();
}
}
}
什么是最大堆:1、二叉树结构 2、父节点大于其两个子节点
shiftUp(Integer[] data,int k)
向上堆排序,添加元素时使用。
shiftDown(int k)
向下堆排序,根元素被拿走时使用。
二叉树的结构有个比较重要的性质:
父节点的下标*2 = 左子节点的下标