publicvoidheapSort(int[] arr) { intn= arr.length; // 建大顶堆 for (inti= n / 2 - 1; i >= 0; i--) { heapify(arr, n, i); } // 排序 for (inti= n - 1; i > 0; i--) { swap(arr, 0, i); // 堆顶放到末尾 heapify(arr, i, 0); // 重新堆化 } }
voidheapify(int[] arr, int n, int i) { intlargest= i; intleft=2 * i + 1; intright=2 * i + 2; if (left < n && arr[left] > arr[largest]) largest = left; if (right < n && arr[right] > arr[largest]) largest = right; if (largest != i) { swap(arr, i, largest); heapify(arr, n, largest); } }
1.3 复杂度分析
情况
时间
空间
最好
( O(n \log n) )
( O(1) )
最坏
( O(n \log n) )
( O(1) )
平均
( O(n \log n) )
( O(1) )
稳定性
不稳定
1.4 特点
原地排序:空间 ( O(1) )
不稳定性:跳跃交换
适合内存受限场景
二、计数排序
2.1 核心思想
统计每个值出现的次数,按顺序输出。
2.2 适用条件
数据范围较小且整数
知道数据的上下界
2.3 实现
publicvoidcountingSort(int[] arr, int maxVal) { int[] count = newint[maxVal + 1]; // 统计 for (int num : arr) { count[num]++; } // 输出 intidx=0; for (inti=0; i <= maxVal; i++) { while (count[i]-- > 0) { arr[idx++] = i; } } }
2.4 稳定版计数排序
publicvoidcountingSortStable(int[] arr, int maxVal) { int[] count = newint[maxVal + 1]; int[] output = newint[arr.length]; for (int num : arr) count[num]++; for (inti=1; i <= maxVal; i++) count[i] += count[i - 1]; // 从后往前保证稳定性 for (inti= arr.length - 1; i >= 0; i--) { output[--count[arr[i]]] = arr[i]; } System.arraycopy(output, 0, arr, 0, arr.length); }
2.5 复杂度
情况
时间
空间
最好/最坏/平均
( O(n + k) )
( O(n + k) )
( k ) = 数据范围
三、基数排序
3.1 核心思想
按位数逐位排序,从低位到高位,每位用计数排序。
3.2 实现
publicvoidradixSort(int[] arr) { intmax= Arrays.stream(arr).max().getAsInt(); for (intexp=1; max / exp > 0; exp *= 10) { countingSortByDigit(arr, exp); } }
voidcountingSortByDigit(int[] arr, int exp) { int[] count = newint[10]; int[] output = newint[arr.length]; for (int num : arr) count[(num / exp) % 10]++; for (inti=1; i < 10; i++) count[i] += count[i - 1]; for (inti= arr.length - 1; i >= 0; i--) { intdigit= (arr[i] / exp) % 10; output[--count[digit]] = arr[i]; } System.arraycopy(output, 0, arr, 0, arr.length); }
3.3 复杂度
( O(d(n + k)) ),( d ) = 位数,( k ) = 进制数
四、桶排序
4.1 核心思想
将数据分到多个桶,每个桶内分别排序。
publicvoidbucketSort(float[] arr) { intn= arr.length; List<Float>[] buckets = newArrayList[n]; for (inti=0; i < n; i++) buckets[i] = newArrayList<>(); // 入桶 for (float num : arr) { intidx= (int) (num * n); buckets[idx].add(num); } // 桶内排序 for (List<Float> bucket : buckets) { Collections.sort(bucket); } // 合并 intidx=0; for (List<Float> bucket : buckets) { for (float num : bucket) { arr[idx++] = num; } } }