目录
1.堆排序的概念
堆排序即利用堆的思想来进行排序,给定一个任意数组,不创建任何的额外空间,就在这个数组上进行排序。堆排序是一个稳定的O(nlogn)时间复杂度的算法。
2.原地堆排序的核心三步
- 先将数组调整为最大堆
- 不断地将当前堆顶和无序数组的最后一个元素进行交换
- 交换之后无序数组的最大值就放在了最终位置,此时进行siftDown
- 重复步骤二和三,当无序数组只剩下一个元素时,整个堆排序完成
3.原地堆排序实例
以数组【1,5,3,8,7,6】为例:
4.冒泡排序与堆排序代码实现
public class SevenSort {
// 无序区间[0...i]
// 有序区间[]
public static void bubbleSort(int[] arr) {
// 外层循环表示要进行元素操作的趟数
for (int i = 0; i < arr.length - 1; i++) {
boolean isSwaped = false;
for (int j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
isSwaped = true;
swap(arr,j,j + 1);
}
}
if (!isSwaped) {
break;
}
}
}
private static void swap(int[] arr,int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void main(String[] args) {
int n = 10_0000;
Random random = new Random();
// 先生成一个大小为10w的随机数数组
int[] data = new int[n];
for (int i = 0; i < data.length; i++) {
data[i] = random.nextInt(100);
}
// int[] data = {1,5,3,8,7,6};
System.out.println(isSorted(data));
heapSort(data);
System.out.println(isSorted(data));
}
public static boolean isSorted(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
if (arr[i] > arr[i + 1]) {
return false;
}
}
return true;
}
// 原地堆排序
public static void heapSort(int[] arr) {
// 1.heapify
for (int i = (arr.length - 1 - 1) / 2; i >= 0; i--) {
siftDown(arr,i,arr.length);
}
// 不断的将当前无序数组的最大值(堆顶) 和 最后一个元素进行交换~
for (int i = arr.length - 1; i >= 0; i--) {
// 将堆顶(最大值) 和 i交换
swap(arr,0,i);
// 进行元素的下沉操作
siftDown(arr,0,i);
}
}
// 在数组arr上进行元素的下沉操作
private static void siftDown(int[] arr, int k, int size) {
int j = 2 * k + 1;
while (j < size) {
if (j + 1 < size && arr[j + 1] > arr[j]) {
j = j + 1;
}
if (arr[k] >= arr[j]) {
// 下沉结束
break;
}else {
swap(arr,k,j);
k = j;
j = 2 * k + 1;
}
}
}
}