堆的概述加代码实现
大根堆和小根堆
普通数组堆化的代码(两种方法)
public static void heapInsert(int[] heap,int index){//先插入到数组的最后一个位置,然后根据那个位置去调整堆[大根]
while(heap[index]>heap[(index-1)/2]){//一直和父亲比较(到了根节点,还没有结束,根节点的父亲还是根节点)
swap(heap,index,(index-1)/2);
index=(index-1)/2;
}
}
public static void heapify(int[] heap, int index, int heapSize){//往下比较交换
int left=index*2+1;//抓到左孩子
while(left<heapSize){
//最大的结点,两个孩子争取,决胜者和父亲争取
int largestIndex=left+1<heapSize&&heap[left+1]>heap[left]?left+1:left;
largestIndex=heap[largestIndex]>heap[index]?largestIndex:index;
if(index==largestIndex) break;//父亲是决胜者
swap(heap,index,largestIndex);
//小的元素来到大的元素原来的位置,(重复while循环,直到left越界,就是index无孩子了)
index=largestIndex;
left=index*2+1;
}
}
public static void swap(int[] arr,int i,int j){
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
堆结构代码
private int[] heap;
private int limit;
private int heapSize;
public MyHeap_code(){
heap=new int[limit];
}
public boolean isEmpty(){
return heapSize==0;
}
public boolean isFull(){
return heapSize==limit;
}
public void push(int value){
if (heapSize==limit) throw new RuntimeException("the heap is full");
heap[heapSize]=value;
heapInsert(heap,heapSize++);
}
public int pop(){
if (heapSize==0) throw new RuntimeException("the heap is empty");
int ans=heap[0];
swap(heap,0,--heapSize);
heapify(heap,0,heapSize);
return ans;
}
堆排序
public static void heapSort(int[] arr) {
if(arr==null || arr.length<2) return;
//建立大根堆
// for (int i = 0; i < arr.length; i++) {
// heapInsert(arr,i);
// }
for(int i=arr.length-1;i>=0;i--) {
//(heapInsert往下越多的结点,越多的结点向上比较的极限是logn)=====logn的极限让多的结点对应
//(heapify)让底下多的结点,调整的时候极限没有到底logn,只有上层的结点的极限才是有logn极限===logn的极限让少数结点对应
heapify(arr, i, arr.length);//从底下向上(调整堆)...比较insert的效率大
}
int heapSize=arr.length;
swap(arr,0,--heapSize);
while(heapSize>0){//n-1次
heapify(arr,0,heapSize);
swap(arr,0,--heapSize);
}
}