堆排序:根据堆结构的性质,对数组进行排序。堆分为大顶堆和小顶堆,大顶堆是指父节点的值总是大于左右子节点的值,小顶堆是指父节点的值总是小于等于左右子节点的值。数组在进行堆排序时,需要将数组先构造成对应的堆结构,然后根据堆的性质,进行排序。大顶堆的第一个元素都是堆中的最大值,小顶堆的第一个元素都是堆中的最小值。
堆排序的时间复杂度是O(nlogn).
大顶堆和小顶堆排序的实现代码分别如下,注意,用大顶堆进行排序,结果为正序,用小顶堆进行排序时,结果为逆序。
import java.util.Arrays;
public class HeapSort_max {
public static void main(String[] args) {
int[] arr = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3 };
System.out.println(Arrays.toString(arr));
heapSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void heapSort(int[] arr) {
if(arr == null || arr.length <= 1){
return;
}
buildMaxHeap(arr);
for(int i = arr.length - 1; i >= 1; i--){
int temp = arr[i];
arr[i] = arr[0];
arr[0] = temp;
maxHeap(arr, i, 0);
}
}
public static void buildMaxHeap(int[] arr) {
if(arr == null || arr.length <= 1)
return;
int half = arr.length/2;
for(int i = half; i >= 0; i--){
maxHeap(arr, arr.length, i);
}
}
public static void maxHeap(int[] arr, int heapSize, int index) {
int left = index * 2 + 1;
int right = index * 2 + 2;
int largest = index;
if(left < heapSize && arr[left] > arr[index])
largest = left;
if(right < heapSize && arr[right] > arr[largest])
largest = right;
if(index != largest){
int temp = arr[index];
arr[index] = arr[largest];
arr[largest] = temp;
maxHeap(arr, heapSize, largest);
}
}
}
import java.util.Arrays;
public class HeapSort_min {
public static void main(String[] args) {
int[] arr = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3 };
System.out.println(Arrays.toString(arr));
heapSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void heapSort(int[] arr) {
if(arr == null || arr.length <= 1){
return;
}
buildMinHeap(arr);
for(int i = arr.length - 1; i >= 1; i--){
int temp = arr[i];
arr[i] = arr[0];
arr[0] = temp;
minHeap(arr, i, 0);
}
}
public static void buildMinHeap(int[] arr) {
if(arr == null || arr.length <= 1)
return;
int half = arr.length/2;
for(int i = half; i >= 0; i--){
minHeap(arr, arr.length, i);
}
}
public static void minHeap(int[] arr, int heapSize, int index) {
int left = index * 2 + 1;
int right = index * 2 + 2;
int smallest = index;
if(left < heapSize && arr[left] < arr[index])
smallest = left;
if(right < heapSize && arr[right] < arr[smallest])
smallest = right;
if(index != smallest){
int temp = arr[index];
arr[index] = arr[smallest];
arr[smallest] = temp;
minHeap(arr, heapSize, smallest);
}
}
}