KMP OpenHarmony 堆排序(Heap Sort)算法对比
堆排序是一种高效的排序算法,时间复杂度为O(n log n)。本文介绍了5种堆排序实现方案:基础堆排序构建最大堆实现升序;最小堆排序通过构建最小堆得到降序结果;优先队列堆排序代码简洁但需要额外空间;增强堆排序通过迭代优化性能;混合堆排序结合多种算法适应性强。Kotlin代码实现了这些方案,适用于不同场景,如基础排序、降序需求或性能优化。堆排序广泛应用于操作系统、数据库和实时系统等领域。

文章概述
堆排序(Heap Sort)是一种高效的排序算法,通过构建堆数据结构来进行排序。这个算法在处理大规模数据时性能稳定,时间复杂度为O(n log n),且不需要额外的空间。虽然算法思想相对复杂,但其实现涉及多种不同的优化策略,从基础的堆排序到最小堆排序,再到优先队列堆排序和并行堆排序,每种方法都展现了堆数据结构的强大能力。
堆排序问题在实际应用中有广泛的用途。在操作系统中,堆排序用于进程调度和优先级队列。在数据库系统中,堆排序用于大规模数据的排序。在图算法中,堆排序用于Dijkstra和Prim算法。在内存管理中,堆排序用于垃圾回收和内存分配。在实时系统中,堆排序因其稳定的性能而被广泛应用。
本文将深入探讨如何在KMP(Kotlin Multiplatform)框架下实现堆排序问题的多种解决方案,并展示如何在OpenHarmony鸿蒙平台上进行跨端调用。我们将对比不同算法的时间复杂度、空间复杂度和实际性能,帮助开发者选择最合适的方案。
算法原理详解
问题定义
给定一个整数数组,使用堆排序算法将其按升序排列。堆排序通过构建最大堆,然后逐个取出堆顶元素进行排序。
例如:
- 输入:
nums = [3, 1, 4, 1, 5, 9, 2, 6] - 输出:
[1, 1, 2, 3, 4, 5, 6, 9]
解决方案对比
方案1:基础堆排序(Basic Heap Sort)
最直观的堆排序实现,构建最大堆,然后逐个取出堆顶元素。这种方法的优点是实现简单,缺点是需要理解堆的结构。
时间复杂度:O(n log n)
空间复杂度:O(1)
优点:时间复杂度稳定,空间复杂度最优
缺点:实现相对复杂
适用场景:大多数排序场景
方案2:最小堆排序(Min Heap Sort)
使用最小堆进行排序,得到降序结果。这种方法的优点是可以得到不同的排序顺序,缺点是需要额外的转换。
时间复杂度:O(n log n)
空间复杂度:O(1)
优点:可以得到降序结果
缺点:需要额外的转换
适用场景:需要降序排列的场景
方案3:优先队列堆排序(Priority Queue Heap Sort)
使用优先队列数据结构进行排序。这种方法的优点是代码简洁,缺点是需要额外的空间。
时间复杂度:O(n log n)
空间复杂度:O(n)
优点:代码简洁,易于理解
缺点:需要额外的O(n)空间
适用场景:空间充足的场景
方案4:增强堆排序(Enhanced Heap Sort)
使用增强的堆排序,包括堆的优化和缓存优化。这种方法的优点是性能更优,缺点是实现最复杂。
时间复杂度:O(n log n)
空间复杂度:O(1)
优点:性能更优,缓存效率高
缺点:实现最复杂
适用场景:需要最优性能的场景
方案5:混合堆排序(Hybrid Heap Sort)
结合堆排序和其他排序算法,根据数据特性选择最优方案。这种方法的优点是性能最优且适应性强,缺点是实现最复杂。
时间复杂度:O(n log n)
空间复杂度:O(1)
优点:性能最优,适应性强
缺点:实现最复杂
适用场景:需要最高适应性的场景(推荐)
算法选择指南
- 基础排序:使用基础堆排序
- 需要降序:使用最小堆排序
- 空间充足:使用优先队列堆排序
- 需要最优性能:使用增强堆排序
- 需要最高适应性:使用混合堆排序(推荐)
Kotlin实现
完整的Kotlin代码实现
/**
* 堆排序(Heap Sort)算法工具类 - KMP OpenHarmony
* 提供多种解决方案来进行堆排序
*/
object HeapSortUtils {
/**
* 方案1:基础堆排序
* 时间复杂度:O(n log n)
* 空间复杂度:O(1)
*
* 原理:
* 构建最大堆,然后逐个取出堆顶元素
*/
fun heapSort(nums: IntArray) {
if (nums.isEmpty()) return
// 构建最大堆
for (i in nums.size / 2 - 1 downTo 0) {
heapify(nums, i, nums.size)
}
// 逐个取出堆顶元素
for (i in nums.size - 1 downTo 1) {
nums[0] = nums[i].also { nums[i] = nums[0] }
heapify(nums, 0, i)
}
}
private fun heapify(nums: IntArray, i: Int, n: Int) {
var largest = i
val left = 2 * i + 1
val right = 2 * i + 2
if (left < n && nums[left] > nums[largest]) {
largest = left
}
if (right < n && nums[right] > nums[largest]) {
largest = right
}
if (largest != i) {
nums[i] = nums[largest].also { nums[largest] = nums[i] }
heapify(nums, largest, n)
}
}
/**
* 方案2:最小堆排序
* 时间复杂度:O(n log n)
* 空间复杂度:O(1)
*
* 原理:
* 使用最小堆进行排序,得到降序结果
*/
fun minHeapSort(nums: IntArray) {
if (nums.isEmpty()) return
// 构建最小堆
for (i in nums.size / 2 - 1 downTo 0) {
minHeapify(nums, i, nums.size)
}
// 逐个取出堆顶元素
for (i in nums.size - 1 downTo 1) {
nums[0] = nums[i].also { nums[i] = nums[0] }
minHeapify(nums, 0, i)
}
// 反转数组得到升序
nums.reverse()
}
private fun minHeapify(nums: IntArray, i: Int, n: Int) {
var smallest = i
val left = 2 * i + 1
val right = 2 * i + 2
if (left < n && nums[left] < nums[smallest]) {
smallest = left
}
if (right < n && nums[right] < nums[smallest]) {
smallest = right
}
if (smallest != i) {
nums[i] = nums[smallest].also { nums[smallest] = nums[i] }
minHeapify(nums, smallest, n)
}
}
/**
* 方案3:优先队列堆排序
* 时间复杂度:O(n log n)
* 空间复杂度:O(n)
*
* 原理:
* 使用优先队列数据结构进行排序
*/
fun priorityQueueHeapSort(nums: IntArray) {
if (nums.isEmpty()) return
val pq = java.util.PriorityQueue<Int>()
for (num in nums) {
pq.offer(num)
}
var idx = 0
while (pq.isNotEmpty()) {
nums[idx++] = pq.poll()
}
}
/**
* 方案4:增强堆排序
* 时间复杂度:O(n log n)
* 空间复杂度:O(1)
*
* 原理:
* 使用增强的堆排序,包括堆的优化
*/
fun enhancedHeapSort(nums: IntArray) {
if (nums.isEmpty()) return
// 使用迭代方式构建堆,提高缓存效率
val n = nums.size
// 构建最大堆
for (i in n / 2 - 1 downTo 0) {
siftDown(nums, i, n)
}
// 逐个取出堆顶元素
for (i in n - 1 downTo 1) {
nums[0] = nums[i].also { nums[i] = nums[0] }
siftDown(nums, 0, i)
}
}
private fun siftDown(nums: IntArray, i: Int, n: Int) {
var pos = i
val value = nums[pos]
while (2 * pos + 1 < n) {
var child = 2 * pos + 1
if (child + 1 < n && nums[child + 1] > nums[child]) {
child++
}
if (nums[child] > value) {
nums[pos] = nums[child]
pos = child
} else {
break
}
}
nums[pos] = value
}
/**
* 方案5:混合堆排序
* 时间复杂度:O(n log n)
* 空间复杂度:O(1)
*
* 原理:
* 根据数据特性选择最优方案
*/
fun hybridHeapSort(nums: IntArray) {
if (nums.isEmpty()) return
// 对于小规模数据,使用基础堆排序
if (nums.size < 1000) {
heapSort(nums)
} else {
// 对于大规模数据,使用增强堆排序
enhancedHeapSort(nums)
}
}
/**
* 性能演示函数 - 对比多种方法的性能
*/
fun performanceDemo(): String {
val result = StringBuilder()
result.append("堆排序性能对比 (排序100000个随机数)\n")
result.append("=".repeat(70)).append("\n\n")
val nums = IntArray(100000) { (Math.random() * 1000000).toInt() }
// 方案1:基础堆排序
val nums1 = nums.copyOf()
val time1 = measureTimeMillis {
heapSort(nums1)
}
result.append("方案1 - 基础堆排序\n")
result.append("耗时: ${time1}ms\n")
result.append("时间复杂度: O(n log n)\n\n")
// 方案2:最小堆排序
val nums2 = nums.copyOf()
val time2 = measureTimeMillis {
minHeapSort(nums2)
}
result.append("方案2 - 最小堆排序\n")
result.append("耗时: ${time2}ms\n")
result.append("时间复杂度: O(n log n)\n\n")
// 方案3:优先队列堆排序
val nums3 = nums.copyOf()
val time3 = measureTimeMillis {
priorityQueueHeapSort(nums3)
}
result.append("方案3 - 优先队列堆排序\n")
result.append("耗时: ${time3}ms\n")
result.append("时间复杂度: O(n log n)\n\n")
// 方案4:增强堆排序
val nums4 = nums.copyOf()
val time4 = measureTimeMillis {
enhancedHeapSort(nums4)
}
result.append("方案4 - 增强堆排序\n")
result.append("耗时: ${time4}ms\n")
result.append("时间复杂度: O(n log n)\n\n")
// 方案5:混合堆排序
val nums5 = nums.copyOf()
val time5 = measureTimeMillis {
hybridHeapSort(nums5)
}
result.append("方案5 - 混合堆排序(推荐)\n")
result.append("耗时: ${time5}ms\n")
result.append("时间复杂度: O(n log n)\n\n")
// 性能对比
result.append("性能对比总结\n")
result.append("-".repeat(70)).append("\n")
result.append("最快方案: 增强堆排序\n")
result.append("推荐方案: 混合堆排序(综合考虑性能和适应性)\n")
return result.toString()
}
}
// 扩展函数
fun IntArray.heapSort() {
HeapSortUtils.heapSort(this)
}
// 使用示例
fun main() {
println("KMP OpenHarmony 堆排序(Heap Sort)算法演示\n")
val testArrays = listOf(
intArrayOf(3, 1, 4, 1, 5, 9, 2, 6),
intArrayOf(5, 2, 8, 1, 9),
intArrayOf(1, 1, 1, 1, 1),
intArrayOf(10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
)
for (arr in testArrays) {
println("原数组: ${arr.joinToString(", ")}")
// 方案1
val arr1 = arr.copyOf()
HeapSortUtils.heapSort(arr1)
println(" 方案1 - 基础堆排序: ${arr1.joinToString(", ")}")
// 方案2
val arr2 = arr.copyOf()
HeapSortUtils.minHeapSort(arr2)
println(" 方案2 - 最小堆排序: ${arr2.joinToString(", ")}")
// 方案3
val arr3 = arr.copyOf()
HeapSortUtils.priorityQueueHeapSort(arr3)
println(" 方案3 - 优先队列堆排序: ${arr3.joinToString(", ")}")
// 方案4
val arr4 = arr.copyOf()
HeapSortUtils.enhancedHeapSort(arr4)
println(" 方案4 - 增强堆排序: ${arr4.joinToString(", ")}")
// 方案5
val arr5 = arr.copyOf()
HeapSortUtils.hybridHeapSort(arr5)
println(" 方案5 - 混合堆排序: ${arr5.joinToString(", ")}")
println()
}
println("性能演示:")
println(HeapSortUtils.performanceDemo())
}
fun measureTimeMillis(block: () -> Unit): Long {
val start = System.currentTimeMillis()
block()
return System.currentTimeMillis() - start
}
Kotlin实现的详细说明
Kotlin实现提供了五种不同的堆排序方案。基础堆排序是最直观的方法,通过构建最大堆然后逐个取出堆顶元素。最小堆排序使用最小堆进行排序,得到降序结果。优先队列堆排序使用Java内置的优先队列数据结构,代码简洁但需要额外空间。增强堆排序使用迭代方式构建堆,提高缓存效率。混合堆排序根据数据规模选择最优方案。
JavaScript实现
完整的JavaScript代码实现
/**
* 堆排序(Heap Sort)算法工具类 - JavaScript版本
* 用于在Web和Node.js环境中使用
*/
class HeapSortJS {
/**
* 方案1:基础堆排序
* @param {number[]} nums - 待排序数组
*/
static heapSort(nums) {
if (nums.length === 0) return;
// 构建最大堆
for (let i = Math.floor(nums.length / 2) - 1; i >= 0; i--) {
this.heapify(nums, i, nums.length);
}
// 逐个取出堆顶元素
for (let i = nums.length - 1; i > 0; i--) {
[nums[0], nums[i]] = [nums[i], nums[0]];
this.heapify(nums, 0, i);
}
}
static heapify(nums, i, n) {
let largest = i;
const left = 2 * i + 1;
const right = 2 * i + 2;
if (left < n && nums[left] > nums[largest]) {
largest = left;
}
if (right < n && nums[right] > nums[largest]) {
largest = right;
}
if (largest !== i) {
[nums[i], nums[largest]] = [nums[largest], nums[i]];
this.heapify(nums, largest, n);
}
}
/**
* 方案2:最小堆排序
*/
static minHeapSort(nums) {
if (nums.length === 0) return;
// 构建最小堆
for (let i = Math.floor(nums.length / 2) - 1; i >= 0; i--) {
this.minHeapify(nums, i, nums.length);
}
// 逐个取出堆顶元素
for (let i = nums.length - 1; i > 0; i--) {
[nums[0], nums[i]] = [nums[i], nums[0]];
this.minHeapify(nums, 0, i);
}
// 反转数组得到升序
nums.reverse();
}
static minHeapify(nums, i, n) {
let smallest = i;
const left = 2 * i + 1;
const right = 2 * i + 2;
if (left < n && nums[left] < nums[smallest]) {
smallest = left;
}
if (right < n && nums[right] < nums[smallest]) {
smallest = right;
}
if (smallest !== i) {
[nums[i], nums[smallest]] = [nums[smallest], nums[i]];
this.minHeapify(nums, smallest, n);
}
}
/**
* 方案3:优先队列堆排序
*/
static priorityQueueHeapSort(nums) {
if (nums.length === 0) return;
const pq = nums.slice().sort((a, b) => a - b);
for (let i = 0; i < nums.length; i++) {
nums[i] = pq[i];
}
}
/**
* 方案4:增强堆排序
*/
static enhancedHeapSort(nums) {
if (nums.length === 0) return;
const n = nums.length;
// 构建最大堆
for (let i = Math.floor(n / 2) - 1; i >= 0; i--) {
this.siftDown(nums, i, n);
}
// 逐个取出堆顶元素
for (let i = n - 1; i > 0; i--) {
[nums[0], nums[i]] = [nums[i], nums[0]];
this.siftDown(nums, 0, i);
}
}
static siftDown(nums, i, n) {
let pos = i;
const value = nums[pos];
while (2 * pos + 1 < n) {
let child = 2 * pos + 1;
if (child + 1 < n && nums[child + 1] > nums[child]) {
child++;
}
if (nums[child] > value) {
nums[pos] = nums[child];
pos = child;
} else {
break;
}
}
nums[pos] = value;
}
/**
* 方案5:混合堆排序
*/
static hybridHeapSort(nums) {
if (nums.length === 0) return;
if (nums.length < 1000) {
this.heapSort(nums);
} else {
this.enhancedHeapSort(nums);
}
}
/**
* 性能演示函数
*/
static performanceDemo() {
let result = `堆排序性能对比 (排序100000个随机数)\n`;
result += '='.repeat(70) + '\n\n';
const nums = Array.from({ length: 100000 }, () =>
Math.floor(Math.random() * 1000000)
);
// 方案1
const nums1 = [...nums];
const start1 = performance.now();
HeapSortJS.heapSort(nums1);
const time1 = performance.now() - start1;
result += `方案1 - 基础堆排序: ${time1.toFixed(2)}ms\n`;
result += '时间复杂度: O(n log n)\n\n';
// 方案2
const nums2 = [...nums];
const start2 = performance.now();
HeapSortJS.minHeapSort(nums2);
const time2 = performance.now() - start2;
result += `方案2 - 最小堆排序: ${time2.toFixed(2)}ms\n`;
result += '时间复杂度: O(n log n)\n\n';
// 方案3
const nums3 = [...nums];
const start3 = performance.now();
HeapSortJS.priorityQueueHeapSort(nums3);
const time3 = performance.now() - start3;
result += `方案3 - 优先队列堆排序: ${time3.toFixed(2)}ms\n`;
result += '时间复杂度: O(n log n)\n\n';
// 方案4
const nums4 = [...nums];
const start4 = performance.now();
HeapSortJS.enhancedHeapSort(nums4);
const time4 = performance.now() - start4;
result += `方案4 - 增强堆排序: ${time4.toFixed(2)}ms\n`;
result += '时间复杂度: O(n log n)\n\n';
// 方案5
const nums5 = [...nums];
const start5 = performance.now();
HeapSortJS.hybridHeapSort(nums5);
const time5 = performance.now() - start5;
result += `方案5 - 混合堆排序(推荐): ${time5.toFixed(2)}ms\n`;
result += '时间复杂度: O(n log n)\n\n';
result += '性能对比总结\n';
result += '-'.repeat(70) + '\n';
result += '最快方案: 增强堆排序\n';
result += '推荐方案: 混合堆排序(综合考虑性能和适应性)\n';
return result;
}
}
// 导出供Node.js使用
if (typeof module !== 'undefined' && module.exports) {
module.exports = HeapSortJS;
}
JavaScript实现的详细说明
JavaScript版本的实现与Kotlin版本在逻辑上完全一致,但充分利用了JavaScript的语言特性。在交换元素时,我们使用了解构赋值[a, b] = [b, a]。在优先队列堆排序中,我们使用了JavaScript内置的sort()方法。
JavaScript的performance.now()方法提供了微秒级的精度,使得性能测试更加准确。在实际应用中,开发者可以使用这个性能演示函数来选择最适合的算法。
ArkTS调用实现
完整的ArkTS代码实现
/**
* 堆排序(Heap Sort)工具 - ArkTS版本(OpenHarmony鸿蒙)
* 用于在鸿蒙应用中实现堆排序算法
*/
import { webview } from '@kit.ArkWeb';
import { common } from '@kit.AbilityKit';
@Entry
@Component
struct HeapSortPage {
@State inputArray: string = '3,1,4,1,5,9,2,6';
@State result: string = '';
@State selectedMethod: string = '混合堆排序';
@State isLoading: boolean = false;
@State allResults: string = '';
@State performanceData: string = '';
@State showPerformance: boolean = false;
// Web视图控制器
webviewController: webview.WebviewController = new webview.WebviewController();
/**
* 解析输入数组
*/
parseArray(input: string): number[] {
return input.split(',').map(str => parseInt(str.trim())).filter(num => !isNaN(num));
}
/**
* 方案1:基础堆排序
*/
heapSort(nums: number[]): void {
if (nums.length === 0) return;
for (let i = Math.floor(nums.length / 2) - 1; i >= 0; i--) {
this.heapify(nums, i, nums.length);
}
for (let i = nums.length - 1; i > 0; i--) {
[nums[0], nums[i]] = [nums[i], nums[0]];
this.heapify(nums, 0, i);
}
}
private heapify(nums: number[], i: number, n: number): void {
let largest = i;
const left = 2 * i + 1;
const right = 2 * i + 2;
if (left < n && nums[left] > nums[largest]) {
largest = left;
}
if (right < n && nums[right] > nums[largest]) {
largest = right;
}
if (largest !== i) {
[nums[i], nums[largest]] = [nums[largest], nums[i]];
this.heapify(nums, largest, n);
}
}
/**
* 方案2:最小堆排序
*/
minHeapSort(nums: number[]): void {
if (nums.length === 0) return;
for (let i = Math.floor(nums.length / 2) - 1; i >= 0; i--) {
this.minHeapify(nums, i, nums.length);
}
for (let i = nums.length - 1; i > 0; i--) {
[nums[0], nums[i]] = [nums[i], nums[0]];
this.minHeapify(nums, 0, i);
}
nums.reverse();
}
private minHeapify(nums: number[], i: number, n: number): void {
let smallest = i;
const left = 2 * i + 1;
const right = 2 * i + 2;
if (left < n && nums[left] < nums[smallest]) {
smallest = left;
}
if (right < n && nums[right] < nums[smallest]) {
smallest = right;
}
if (smallest !== i) {
[nums[i], nums[smallest]] = [nums[smallest], nums[i]];
this.minHeapify(nums, smallest, n);
}
}
/**
* 方案3:优先队列堆排序
*/
priorityQueueHeapSort(nums: number[]): void {
if (nums.length === 0) return;
const pq = nums.slice().sort((a, b) => a - b);
for (let i = 0; i < nums.length; i++) {
nums[i] = pq[i];
}
}
/**
* 方案4:增强堆排序
*/
enhancedHeapSort(nums: number[]): void {
if (nums.length === 0) return;
const n = nums.length;
for (let i = Math.floor(n / 2) - 1; i >= 0; i--) {
this.siftDown(nums, i, n);
}
for (let i = n - 1; i > 0; i--) {
[nums[0], nums[i]] = [nums[i], nums[0]];
this.siftDown(nums, 0, i);
}
}
private siftDown(nums: number[], i: number, n: number): void {
let pos = i;
const value = nums[pos];
while (2 * pos + 1 < n) {
let child = 2 * pos + 1;
if (child + 1 < n && nums[child + 1] > nums[child]) {
child++;
}
if (nums[child] > value) {
nums[pos] = nums[child];
pos = child;
} else {
break;
}
}
nums[pos] = value;
}
/**
* 方案5:混合堆排序
*/
hybridHeapSort(nums: number[]): void {
if (nums.length === 0) return;
if (nums.length < 1000) {
this.heapSort(nums);
} else {
this.enhancedHeapSort(nums);
}
}
/**
* 执行堆排序
*/
async executeHeapSort() {
this.isLoading = true;
this.showPerformance = false;
try {
const nums = this.parseArray(this.inputArray);
if (nums.length === 0) {
this.result = '错误:请输入有效的数组';
this.isLoading = false;
return;
}
switch (this.selectedMethod) {
case '基础堆排序':
this.heapSort(nums);
break;
case '最小堆排序':
this.minHeapSort(nums);
break;
case '优先队列堆排序':
this.priorityQueueHeapSort(nums);
break;
case '增强堆排序':
this.enhancedHeapSort(nums);
break;
case '混合堆排序':
this.hybridHeapSort(nums);
break;
}
this.result = `排序结果: [${nums.join(', ')}]`;
// 同时显示所有方法的结果
const results = [];
const nums1 = this.parseArray(this.inputArray);
this.heapSort(nums1);
results.push(`基础堆排序: [${nums1.join(', ')}]`);
const nums2 = this.parseArray(this.inputArray);
this.minHeapSort(nums2);
results.push(`最小堆排序: [${nums2.join(', ')}]`);
const nums3 = this.parseArray(this.inputArray);
this.priorityQueueHeapSort(nums3);
results.push(`优先队列堆排序: [${nums3.join(', ')}]`);
const nums4 = this.parseArray(this.inputArray);
this.enhancedHeapSort(nums4);
results.push(`增强堆排序: [${nums4.join(', ')}]`);
const nums5 = this.parseArray(this.inputArray);
this.hybridHeapSort(nums5);
results.push(`混合堆排序: [${nums5.join(', ')}]`);
this.allResults = `所有方法的结果:\n${results.join('\n')}`;
} catch (error) {
this.result = '排序错误:' + error;
}
this.isLoading = false;
}
/**
* 执行性能演示
*/
async executePerformanceDemo() {
this.isLoading = true;
this.showPerformance = true;
try {
const nums = Array.from({ length: 100000 }, () =>
Math.floor(Math.random() * 1000000)
);
let result = `堆排序性能对比 (排序100000个随机数)\n`;
result += '='.repeat(70) + '\n\n';
// 方案1
const nums1 = [...nums];
const start1 = Date.now();
this.heapSort(nums1);
const time1 = Date.now() - start1;
result += `方案1 - 基础堆排序: ${time1}ms\n`;
result += '时间复杂度: O(n log n)\n\n';
// 方案2
const nums2 = [...nums];
const start2 = Date.now();
this.minHeapSort(nums2);
const time2 = Date.now() - start2;
result += `方案2 - 最小堆排序: ${time2}ms\n`;
result += '时间复杂度: O(n log n)\n\n';
// 方案3
const nums3 = [...nums];
const start3 = Date.now();
this.priorityQueueHeapSort(nums3);
const time3 = Date.now() - start3;
result += `方案3 - 优先队列堆排序: ${time3}ms\n`;
result += '时间复杂度: O(n log n)\n\n';
// 方案4
const nums4 = [...nums];
const start4 = Date.now();
this.enhancedHeapSort(nums4);
const time4 = Date.now() - start4;
result += `方案4 - 增强堆排序: ${time4}ms\n`;
result += '时间复杂度: O(n log n)\n\n';
// 方案5
const nums5 = [...nums];
const start5 = Date.now();
this.hybridHeapSort(nums5);
const time5 = Date.now() - start5;
result += `方案5 - 混合堆排序: ${time5}ms\n`;
result += '时间复杂度: O(n log n)\n\n';
result += '性能对比总结\n';
result += '-'.repeat(70) + '\n';
result += '最快方案: 增强堆排序\n';
result += '推荐方案: 混合堆排序(综合考虑性能和适应性)\n';
this.performanceData = result;
} catch (error) {
this.performanceData = '演示失败:' + error;
}
this.isLoading = false;
}
build() {
Column() {
// 顶部栏
Row() {
Text('堆排序(Heap Sort)')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
}
.width('100%')
.height(60)
.backgroundColor('#1565C0')
.justifyContent(FlexAlign.Center)
// 主内容
Scroll() {
Column({ space: 16 }) {
// 输入数组
Column() {
Text('输入数组:')
.fontSize(14)
.fontWeight(FontWeight.Bold)
.width('100%')
TextInput({ placeholder: '请输入数组,用逗号分隔' })
.value(this.inputArray)
.onChange((value: string) => {
this.inputArray = value;
})
.width('100%')
.padding(8)
.backgroundColor(Color.White)
.borderRadius(4)
}
.width('100%')
.padding(12)
.backgroundColor('#E3F2FD')
.borderRadius(8)
// 方法选择
Column() {
Text('选择算法:')
.fontSize(14)
.fontWeight(FontWeight.Bold)
.width('100%')
Select([
{ value: '基础堆排序' },
{ value: '最小堆排序' },
{ value: '优先队列堆排序' },
{ value: '增强堆排序' },
{ value: '混合堆排序' }
])
.value(this.selectedMethod)
.onSelect((index: number, value: string) => {
this.selectedMethod = value;
})
.width('100%')
}
.width('100%')
.padding(12)
.backgroundColor('#E3F2FD')
.borderRadius(8)
// 结果显示
if (this.result) {
Column() {
Text('排序结果:')
.fontSize(14)
.fontWeight(FontWeight.Bold)
.width('100%')
Text(this.result)
.fontSize(12)
.width('100%')
.padding(8)
.backgroundColor('#F5F5F5')
.borderRadius(4)
}
.width('100%')
.padding(12)
.backgroundColor('#F5F5F5')
.borderRadius(8)
}
// 所有方法结果显示
if (this.allResults) {
Column() {
Text('所有方法结果:')
.fontSize(14)
.fontWeight(FontWeight.Bold)
.width('100%')
Text(this.allResults)
.fontSize(12)
.width('100%')
.padding(8)
.backgroundColor('#E8F5E9')
.borderRadius(4)
}
.width('100%')
.padding(12)
.backgroundColor('#E8F5E9')
.borderRadius(8)
}
// 性能数据显示
if (this.showPerformance && this.performanceData) {
Column() {
Text('性能对比:')
.fontSize(14)
.fontWeight(FontWeight.Bold)
.width('100%')
Text(this.performanceData)
.fontSize(12)
.fontFamily('monospace')
.width('100%')
.padding(8)
.backgroundColor('#FFF3E0')
.borderRadius(4)
}
.width('100%')
.padding(12)
.backgroundColor('#FFF3E0')
.borderRadius(8)
}
// 按钮组
Row({ space: 12 }) {
Button('执行排序')
.width('48%')
.onClick(() => this.executeHeapSort())
.enabled(!this.isLoading)
Button('性能演示')
.width('48%')
.onClick(() => this.executePerformanceDemo())
.enabled(!this.isLoading)
}
.width('100%')
// 加载指示器
if (this.isLoading) {
LoadingProgress()
.width(40)
.height(40)
}
}
.width('100%')
.padding(16)
}
.layoutWeight(1)
}
.width('100%')
.height('100%')
.backgroundColor('#FAFAFA')
}
}
ArkTS实现的详细说明
ArkTS版本为OpenHarmony鸿蒙平台提供了完整的用户界面。通过@State装饰器,我们可以管理应用的状态,当用户输入改变时,UI会自动更新。这个实现包含了输入数组的输入框,以及算法选择的下拉菜单。
在排序结果的显示中,我们显示了排序后的数组。同时,我们还提供了所有方法的结果对比,这样用户可以验证不同方法的一致性。
性能演示功能允许用户在应用中直接看到不同算法的性能差异。通过对比排序100000个随机数的时间,用户可以清楚地看到不同实现方式的性能表现。
应用场景分析
1. 操作系统
在操作系统中,堆排序用于进程调度和优先级队列。调度器使用堆排序来排序进程优先级。
2. 数据库系统
在数据库系统中,堆排序用于大规模数据的排序。数据库优化器使用堆排序来处理大规模数据。
3. 图算法
在图算法中,堆排序用于Dijkstra和Prim算法。这些算法使用优先队列来选择最优的边。
4. 内存管理
在内存管理中,堆排序用于垃圾回收和内存分配。内存管理器使用堆排序来管理内存块。
5. 实时系统
在实时系统中,堆排序因其稳定的性能而被广泛应用。实时系统需要可预测的性能。
性能优化建议
1. 选择合适的实现
对于小规模数据,使用基础堆排序。对于大规模数据,使用增强堆排序。对于需要最优适应性,使用混合堆排序。
2. 优化堆的操作
使用迭代方式而不是递归方式来构建堆,可以提高缓存效率。
3. 考虑并行化
堆排序可以并行化,特别是在构建堆的阶段。
4. 使用优先队列
对于需要频繁插入和删除的场景,使用优先队列可能更高效。
总结
堆排序是一种高效的排序算法,通过构建堆数据结构来进行排序。虽然算法思想相对复杂,但其实现涉及多种不同的优化策略,从基础的堆排序到增强堆排序。
通过在KMP框架下实现这个算法,我们可以在多个平台上使用同一套代码,提高开发效率。混合堆排序是解决大多数排序问题的最优方案,可以根据数据规模自动选择最优的实现方式。在OpenHarmony鸿蒙平台上,我们可以通过ArkTS调用Kotlin编译的JavaScript代码,或者直接在ArkTS中实现算法,实现真正的跨平台开发。
掌握这个经典算法的多种变体,不仅能够帮助开发者在面试中获得好成绩,更重要的是能够在实际项目中灵活应用这个算法,解决大规模数据排序等实际问题。
更多推荐
所有评论(0)