基础排序:堆排序
先对堆的做个了解:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。
根据大根堆的定义可以知道,大根堆的根节点是最大的,那么我们可以从大根堆中取出根节点,将它放在最后,然后对最后一个数之前的数重新进行大根堆的构建,然后前面的数又是一个大根堆,那么可以重复上面的动作。直到整个大根堆都完成取值。
堆排序:
- 将原始的数组构建为一个大根堆
- 将第一个数(最大的根节点)和最后一个数交换
- 重新对之前的数进行大根堆构建(排除了最后一个数)
- 重复第二和第三步,直到排序完成(不用再进行重新构建大根堆,即全部完成)
public class HeapSort {
public void heapSort(int[] arr){
if(arr == null || arr.length < 2){
return;
}
//构建大根堆
for(int i = 0;i < arr.length;i++){
heapInsert(arr,i);
}
//将根堆的和最后一个数交换,并对前面的大根堆重新进行构建
int size = arr.length;
swap(arr,0,--size);
while(size > 0){
heapify(arr,0,size);
swap(arr,0,--size);
}
}
private void heapInsert(int[] arr,int index){
while(arr[index] > arr[(index - 1) / 2]){
swap(arr,index,(index - 1) / 2);
index = (index - 1) / 2;
}
}
private void heapify(int[] arr,int index,int size){
int left = index * 2 + 1;
while(left < size){
int largest = left + 1 < size && arr[left] < arr[left + 1] ? left + 1 : left;
largest = arr[index] < arr[largest] ? largest : index;
if(largest == index){
break;
}
swap(arr,index,largest);
index = largest;
left = index * 2 + 1;
}
}
private void swap(int[] arr,int i,int j){
int tem = arr[i];
arr[i] = arr[j];
arr[j] = tem;
}
private boolean compare(int[] arr){
int[] copy = new int[arr.length];
for(int i = 0;i < copy.length;i++){
copy[i] = arr[i];
}
Arrays.sort(copy);
for(int i = 0;i < arr.length;i++){
if(copy[i] != arr[i]){
return false;
}
}
return true;
}
public static void main(String[] args) {
int[] arr = new int[(int) ((100+1)*Math.random())];
for(int i = 0;i < arr.length;i++){
arr[i] = (int)(((100 + 1) * Math.random())) - (int) ((100 + 1) * Math.random());
}
HeapSort sort = new HeapSort();
sort.heapSort(arr);
System.out.println(sort.compare(arr));
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
}