堆排序是不稳定排序
注:排升序要建大堆;排降序要建小堆。
排序原理:
直观上理解,例如想进行升序排序,就可以建立小堆,每次取堆顶元素,这样就行程了升序,但这种思路不是原地排序!!!
为了达到原地排序的效果,就需要建立一个大堆,之后每次删除堆顶元素(拿堆顶元素和堆的最后一个元素交换位置),此时最大值就到了最后的位置。
从 0 号元素进行向下调整,是前面的元素重新成为堆,再继续只想上面的操作。
public static void heapSort(int[] arr) {
creatHeap(arr);
int heapSize = arr.length;
for (int i = 0; i < arr.length; i++) {
swap(arr, 0, heapSize - 1);
heapSize--;
shiftDown(arr, heapSize, 0);
}
}
public static void creatHeap(int[] arr) {
for (int i = (arr.length - 1 - 1) / 2; i >= 0; i--) {
shiftDown(arr, arr.length, i);
}
}
public static void shiftDown(int[] arr, int size, int index) {
int parent = index;
int child = 2*parent + 1;
while (child < size) {
if (child + 1 < size && arr[child + 1] > arr[child]) {
child = child + 1;
}
if (arr[parent] < arr[child]) {
swap(arr, parent, child);
}
parent = child;
child = 2*parent + 1;
}
}
public static void swap(int[] arr, int x, int y) {
int tmp = arr[x];
arr[x] = arr[y];
arr[y] = tmp;
}