一、堆
堆:完全二叉树
堆:大根堆和小根堆;
大根堆:二叉树的所有子树的根节点最大;
小根堆:二叉树的所有子树的根节点最小;
二、堆的基本操作
1、在一个大根数中插入一个节点,构成新的大根数,heapInsert函数
思路:将插入的数与其父节点进行比较,若大于其父节点则交换;
代码:
public static void heapInsert(int[] arr,int index){
while(arr[index]>arr[(index-1)/2]){
swap(arr,index,(index-1)/2);
index=(index-1)/2;
}
}
2、在一个大根数中,若某一个index处的节点变小,调整得到新的节点heapIfy函数
public static void heapIfy(int[] arr,int index,int heapSize){
int left=(index*2+1);
int largest;
while(left<heapSize){
largest=(left+1)<heapSize && arr[left+1]>arr[left]? left+1: left;
if(arr[index]>=arr[largest]){
break;
}
swap(arr,index,largest);
index=largest;
left=(index*2+1);
}
}
3、在一个大根树中,弹出顶点
思路:交换首节点和尾节点,再对交换后的首节点进行heapIfy操作。
public static void heapIfy(int[] arr,int index,int heapSize){
int left=(index*2+1);
int largest;
while(left<heapSize){
largest=(left+1)<heapSize && arr[left+1]>arr[left]? left+1: left;
if(arr[index]>=arr[largest]){
break;
}
swap(arr,index,largest);
index=largest;
left=(index*2+1);
}
}
public static void popheapTop(int[] arr,int heapSize){
swap(arr,0,heapSize-1);
heapSize--;
heapIfy(arr,0,heapSize);
}
4、堆排序
思路:大根堆的首节点,是所有元素的MAX值。
Step1:首先将数组排成一个大根堆;(heapInsert操作)
Step2:每次弹出大根堆的首节点,再进行heapIfy操作。
public static void heapSort(int[] arr){
for(int i=0; i<arr.length;i++){
heapInsert(arr,i);
}
int heapSize=arr.length;
while(heapSize>0){
swap(arr,0,heapSize-1);
heapSize--;
heapIfy(arr,0,heapSize);
}
}