堆排没有用到递归,一般堆排是两个步骤,
1、建立堆
2、不断的调整堆,进行排序
首先,我们学习堆排就必须了解什么是堆,堆其实是一种比较特殊的数据结构,分为大根堆和小根堆,堆有两个性质
1、它是一个完全二叉树,每个节点都比它的子树所有节点大(大根堆)
2、由于他是一个完全二叉树,那么它的每个位置都与数组的每个下标一一对应
由于这两种性质,我们就可将数组看做一个完全二叉树,
第一步(大根堆),将这个完全二叉树转换成堆,从第一个节点开始,与他的父节点比较大小,如果比他的父节点要大,那么他就和父节点进行交换,然后继续与父节点比较,如果比父节点要小,那么就停止比较,它也就找到了它的位置。以此类推,从第一个节点到最后一个节点都是如此操作。
第二步、找到未被交换的最后一个节点,此时第一个节点肯定是最大的,将第一个节点与最后一个节点进行交换,此时整个数组不再是一个大根堆(不包含最后一个数),对数组进行调整,将第一个节点与左右孩子进行比较,如果比左右孩子大,不用调整,如果比左右孩子小,交换,继续,向下比较,直到比较比左右孩子小,或者走到倒数第二个数(倒数第一个已经被交换了)。
重复第二步骤
public void heapSort (int[] arr) {
if (arr==null || arr.length ==2) {
return;
}
for (int i = 0; i<= arr.length-1;i ++) {
buildHeap(arr,i);
}
int size = arr.length;
swap(arr,0,--size);
while (size>0) {
filHeap(arr,0,size);
swap(arr,0,--size);
}
}
public void buildHeap (int[] arr,int index) {
while (arr[index] > arr[(index+1)/2]){
swap(arr,index,(index+1)/2);
index = (index+1)/2;
}
}
public void filHeap (int[] arr , int index, int size) {
int left = index*2 +1;
while (left <size) {
int largest = arr[left+1]<size && arr[left+1]>arr[left]? left+1 : left;
largest = arr[largest]>arr[index] ? largest:index;
if (index ==largest) {
return;
}
swap(arr,index,largest);
index =largest;
left = index*2 +1;
}