在这里插入图片描述
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

文章概述

基数排序(Radix Sort)是一种非比较排序算法,通过按位数逐位排序来进行排序。这个算法在处理大整数和字符串排序时性能优异,时间复杂度为O(d * (n + k)),其中d是数字位数,k是基数。虽然算法思想相对简单,但其实现涉及多种不同的优化策略,从最低有效位优先到最高有效位优先,再到并行基数排序和混合基数排序,每种方法都展现了非比较排序的强大能力。

基数排序问题在实际应用中有广泛的用途。在数据库系统中,基数排序用于快速排序大整数和字符串。在网络数据处理中,基数排序用于IP地址和MAC地址排序。在图形处理中,基数排序用于颜色值排序。在密码学中,基数排序用于密钥排序。在科学计算中,基数排序用于浮点数排序。

本文将深入探讨如何在KMP(Kotlin Multiplatform)框架下实现基数排序问题的多种解决方案,并展示如何在OpenHarmony鸿蒙平台上进行跨端调用。我们将对比不同算法的时间复杂度、空间复杂度和实际性能,帮助开发者选择最合适的方案。

算法原理详解

问题定义

给定一个非负整数数组,使用基数排序算法将其按升序排列。基数排序通过按位数逐位排序,从最低有效位或最高有效位开始,逐步对更高位进行排序。

例如:

  • 输入:nums = [170, 45, 75, 90, 2, 802, 24, 2, 66]
  • 输出:[2, 2, 24, 45, 66, 75, 90, 170, 802]

解决方案对比

方案1:最低有效位优先(LSD Radix Sort)

从最低有效位开始排序,逐步向最高有效位进行排序。这种方法的优点是实现简单,缺点是需要多次遍历。

时间复杂度:O(d * (n + k))
空间复杂度:O(n + k)
优点:实现简单,易于理解
缺点:需要多次遍历
适用场景:整数排序

方案2:最高有效位优先(MSD Radix Sort)

从最高有效位开始排序,递归地对每个桶进行排序。这种方法的优点是性能更好,缺点是实现相对复杂。

时间复杂度:O(d * (n + k))
空间复杂度:O(n + k)
优点:性能更好,可以提前终止
缺点:实现相对复杂
适用场景:大整数排序

方案3:字符串基数排序(String Radix Sort)

用于排序字符串,按字符逐位排序。这种方法的优点是可以处理字符串,缺点是实现最复杂。

时间复杂度:O(d * (n + k))
空间复杂度:O(n + k)
优点:可以处理字符串
缺点:实现最复杂
适用场景:字符串排序

方案4:基数排序优化版(Optimized Radix Sort)

使用多个基数和优化的计数排序。这种方法的优点是性能最优,缺点是实现最复杂。

时间复杂度:O(d * (n + k))
空间复杂度:O(n + k)
优点:性能最优,减少遍历次数
缺点:实现最复杂
适用场景:需要最优性能的场景

方案5:混合基数排序(Hybrid Radix Sort)

结合基数排序和其他排序算法,根据数据特性选择最优方案。这种方法的优点是性能最优且适应性强,缺点是实现最复杂。

时间复杂度:O(d * (n + k))到O(n log n)
空间复杂度:O(n + k)
优点:性能最优,适应性强
缺点:实现最复杂
适用场景:需要最高适应性的场景(推荐)

算法选择指南

  • 基础整数排序:使用最低有效位优先
  • 大整数排序:使用最高有效位优先
  • 字符串排序:使用字符串基数排序
  • 需要最优性能:使用基数排序优化版
  • 需要最高适应性:使用混合基数排序(推荐)

Kotlin实现

完整的Kotlin代码实现

/**
 * 基数排序(Radix Sort)算法工具类 - KMP OpenHarmony
 * 提供多种解决方案来进行基数排序
 */
object RadixSortUtils {
    
    /**
     * 方案1:最低有效位优先(LSD Radix Sort)
     * 时间复杂度:O(d * (n + k))
     * 空间复杂度:O(n + k)
     * 
     * 原理:
     * 从最低有效位开始排序
     * 逐步向最高有效位进行排序
     */
    fun radixSortLSD(nums: IntArray) {
        if (nums.isEmpty()) return
        
        val max = nums.maxOrNull() ?: return
        var exp = 1
        
        while (max / exp > 0) {
            countingSortByDigit(nums, exp)
            exp *= 10
        }
    }
    
    private fun countingSortByDigit(nums: IntArray, exp: Int) {
        val count = IntArray(10)
        for (num in nums) {
            count[(num / exp) % 10]++
        }
        
        for (i in 1..9) {
            count[i] += count[i - 1]
        }
        
        val output = IntArray(nums.size)
        for (i in nums.size - 1 downTo 0) {
            output[count[(nums[i] / exp) % 10] - 1] = nums[i]
            count[(nums[i] / exp) % 10]--
        }
        
        for (i in nums.indices) {
            nums[i] = output[i]
        }
    }
    
    /**
     * 方案2:最高有效位优先(MSD Radix Sort)
     * 时间复杂度:O(d * (n + k))
     * 空间复杂度:O(n + k)
     * 
     * 原理:
     * 从最高有效位开始排序
     * 递归地对每个桶进行排序
     */
    fun radixSortMSD(nums: IntArray) {
        if (nums.isEmpty()) return
        
        val max = nums.maxOrNull() ?: return
        var exp = 1
        while (max / (exp * 10) > 0) {
            exp *= 10
        }
        
        radixSortMSDHelper(nums, 0, nums.size - 1, exp)
    }
    
    private fun radixSortMSDHelper(nums: IntArray, left: Int, right: Int, exp: Int) {
        if (left >= right || exp == 0) return
        
        val buckets = Array(10) { mutableListOf<Int>() }
        for (i in left..right) {
            buckets[(nums[i] / exp) % 10].add(nums[i])
        }
        
        var idx = left
        for (bucket in buckets) {
            for (num in bucket) {
                nums[idx++] = num
            }
        }
        
        idx = left
        for (bucket in buckets) {
            if (bucket.isNotEmpty()) {
                val bucketArray = bucket.toIntArray()
                radixSortMSDHelper(bucketArray, 0, bucketArray.size - 1, exp / 10)
                for (num in bucketArray) {
                    nums[idx++] = num
                }
            }
        }
    }
    
    /**
     * 方案3:字符串基数排序
     * 时间复杂度:O(d * (n + k))
     * 空间复杂度:O(n + k)
     * 
     * 原理:
     * 用于排序字符串
     * 按字符逐位排序
     */
    fun radixSortString(strs: Array<String>) {
        if (strs.isEmpty()) return
        
        val maxLen = strs.maxOfOrNull { it.length } ?: return
        
        for (pos in maxLen - 1 downTo 0) {
            countingSortByChar(strs, pos)
        }
    }
    
    private fun countingSortByChar(strs: Array<String>, pos: Int) {
        val count = IntArray(256)
        for (str in strs) {
            val ch = if (pos < str.length) str[pos].code else 0
            count[ch]++
        }
        
        for (i in 1..255) {
            count[i] += count[i - 1]
        }
        
        val output = Array(strs.size) { "" }
        for (i in strs.size - 1 downTo 0) {
            val ch = if (pos < strs[i].length) strs[i][pos].code else 0
            output[count[ch] - 1] = strs[i]
            count[ch]--
        }
        
        for (i in strs.indices) {
            strs[i] = output[i]
        }
    }
    
    /**
     * 方案4:基数排序优化版
     * 时间复杂度:O(d * (n + k))
     * 空间复杂度:O(n + k)
     * 
     * 原理:
     * 使用多个基数和优化的计数排序
     */
    fun radixSortOptimized(nums: IntArray) {
        if (nums.isEmpty()) return
        
        val max = nums.maxOrNull() ?: return
        
        // 使用基数256而不是10,减少遍历次数
        var exp = 1
        while (max / exp > 0) {
            countingSortByDigitOptimized(nums, exp)
            exp *= 256
        }
    }
    
    private fun countingSortByDigitOptimized(nums: IntArray, exp: Int) {
        val count = IntArray(256)
        for (num in nums) {
            count[(num / exp) % 256]++
        }
        
        for (i in 1..255) {
            count[i] += count[i - 1]
        }
        
        val output = IntArray(nums.size)
        for (i in nums.size - 1 downTo 0) {
            output[count[(nums[i] / exp) % 256] - 1] = nums[i]
            count[(nums[i] / exp) % 256]--
        }
        
        for (i in nums.indices) {
            nums[i] = output[i]
        }
    }
    
    /**
     * 方案5:混合基数排序
     * 时间复杂度:O(d * (n + k))到O(n log n)
     * 空间复杂度:O(n + k)
     * 
     * 原理:
     * 根据数据特性选择最优方案
     */
    fun radixSortHybrid(nums: IntArray) {
        if (nums.isEmpty()) return
        
        val max = nums.maxOrNull() ?: return
        
        // 对于小范围数据,使用计数排序
        if (max < 1000) {
            nums.sort()
            return
        }
        
        // 对于大范围数据,使用基数排序
        radixSortLSD(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:LSD基数排序
        val nums1 = nums.copyOf()
        val time1 = measureTimeMillis {
            radixSortLSD(nums1)
        }
        result.append("方案1 - LSD基数排序\n")
        result.append("耗时: ${time1}ms\n")
        result.append("时间复杂度: O(d * (n + k))\n\n")
        
        // 方案2:MSD基数排序
        val nums2 = nums.copyOf()
        val time2 = measureTimeMillis {
            radixSortMSD(nums2)
        }
        result.append("方案2 - MSD基数排序\n")
        result.append("耗时: ${time2}ms\n")
        result.append("时间复杂度: O(d * (n + k))\n\n")
        
        // 方案3:字符串基数排序(转换为字符串)
        val strs = Array(100000) { (Math.random() * 1000000).toInt().toString() }
        val time3 = measureTimeMillis {
            radixSortString(strs)
        }
        result.append("方案3 - 字符串基数排序\n")
        result.append("耗时: ${time3}ms\n")
        result.append("时间复杂度: O(d * (n + k))\n\n")
        
        // 方案4:基数排序优化版
        val nums4 = nums.copyOf()
        val time4 = measureTimeMillis {
            radixSortOptimized(nums4)
        }
        result.append("方案4 - 基数排序优化版\n")
        result.append("耗时: ${time4}ms\n")
        result.append("时间复杂度: O(d * (n + k))\n\n")
        
        // 方案5:混合基数排序
        val nums5 = nums.copyOf()
        val time5 = measureTimeMillis {
            radixSortHybrid(nums5)
        }
        result.append("方案5 - 混合基数排序(推荐)\n")
        result.append("耗时: ${time5}ms\n")
        result.append("时间复杂度: O(d * (n + k))到O(n log n)\n\n")
        
        // 性能对比
        result.append("性能对比总结\n")
        result.append("-".repeat(70)).append("\n")
        result.append("最快方案: LSD基数排序\n")
        result.append("推荐方案: 混合基数排序(综合考虑性能和适应性)\n")
        
        return result.toString()
    }
}

// 扩展函数
fun IntArray.radixSort() {
    RadixSortUtils.radixSortLSD(this)
}

// 使用示例
fun main() {
    println("KMP OpenHarmony 基数排序(Radix Sort)算法演示\n")
    
    val testArrays = listOf(
        intArrayOf(170, 45, 75, 90, 2, 802, 24, 2, 66),
        intArrayOf(5, 2, 8, 1, 9),
        intArrayOf(100, 100, 100, 100),
        intArrayOf(999, 888, 777, 666, 555, 444, 333, 222, 111)
    )
    
    for (arr in testArrays) {
        println("原数组: ${arr.joinToString(", ")}")
        
        // 方案1
        val arr1 = arr.copyOf()
        RadixSortUtils.radixSortLSD(arr1)
        println("  方案1 - LSD基数排序: ${arr1.joinToString(", ")}")
        
        // 方案2
        val arr2 = arr.copyOf()
        RadixSortUtils.radixSortMSD(arr2)
        println("  方案2 - MSD基数排序: ${arr2.joinToString(", ")}")
        
        // 方案4
        val arr4 = arr.copyOf()
        RadixSortUtils.radixSortOptimized(arr4)
        println("  方案4 - 基数排序优化版: ${arr4.joinToString(", ")}")
        
        // 方案5
        val arr5 = arr.copyOf()
        RadixSortUtils.radixSortHybrid(arr5)
        println("  方案5 - 混合基数排序: ${arr5.joinToString(", ")}")
        
        println()
    }
    
    println("性能演示:")
    println(RadixSortUtils.performanceDemo())
}

fun measureTimeMillis(block: () -> Unit): Long {
    val start = System.currentTimeMillis()
    block()
    return System.currentTimeMillis() - start
}

Kotlin实现的详细说明

Kotlin实现提供了五种不同的基数排序方案。LSD基数排序从最低有效位开始排序,实现简单。MSD基数排序从最高有效位开始排序,使用递归方式。字符串基数排序用于排序字符串数据。基数排序优化版使用基数256而不是10,减少遍历次数。混合基数排序根据数据范围选择最优方案。

JavaScript实现

完整的JavaScript代码实现

/**
 * 基数排序(Radix Sort)算法工具类 - JavaScript版本
 * 用于在Web和Node.js环境中使用
 */
class RadixSortJS {
    /**
     * 方案1:最低有效位优先(LSD Radix Sort)
     * @param {number[]} nums - 待排序数组
     */
    static radixSortLSD(nums) {
        if (nums.length === 0) return;
        
        const max = Math.max(...nums);
        let exp = 1;
        
        while (Math.floor(max / exp) > 0) {
            this.countingSortByDigit(nums, exp);
            exp *= 10;
        }
    }
    
    static countingSortByDigit(nums, exp) {
        const count = new Array(10).fill(0);
        for (const num of nums) {
            count[Math.floor((num / exp) % 10)]++;
        }
        
        for (let i = 1; i < 10; i++) {
            count[i] += count[i - 1];
        }
        
        const output = new Array(nums.length);
        for (let i = nums.length - 1; i >= 0; i--) {
            output[count[Math.floor((nums[i] / exp) % 10)] - 1] = nums[i];
            count[Math.floor((nums[i] / exp) % 10)]--;
        }
        
        for (let i = 0; i < nums.length; i++) {
            nums[i] = output[i];
        }
    }
    
    /**
     * 方案2:最高有效位优先(MSD Radix Sort)
     */
    static radixSortMSD(nums) {
        if (nums.length === 0) return;
        
        const max = Math.max(...nums);
        let exp = 1;
        while (Math.floor(max / (exp * 10)) > 0) {
            exp *= 10;
        }
        
        this.radixSortMSDHelper(nums, 0, nums.length - 1, exp);
    }
    
    static radixSortMSDHelper(nums, left, right, exp) {
        if (left >= right || exp === 0) return;
        
        const buckets = Array.from({ length: 10 }, () => []);
        for (let i = left; i <= right; i++) {
            buckets[Math.floor((nums[i] / exp) % 10)].push(nums[i]);
        }
        
        let idx = left;
        for (const bucket of buckets) {
            for (const num of bucket) {
                nums[idx++] = num;
            }
        }
        
        idx = left;
        for (const bucket of buckets) {
            if (bucket.length > 0) {
                this.radixSortMSDHelper(bucket, 0, bucket.length - 1, Math.floor(exp / 10));
                for (const num of bucket) {
                    nums[idx++] = num;
                }
            }
        }
    }
    
    /**
     * 方案3:字符串基数排序
     */
    static radixSortString(strs) {
        if (strs.length === 0) return;
        
        const maxLen = Math.max(...strs.map(s => s.length));
        
        for (let pos = maxLen - 1; pos >= 0; pos--) {
            this.countingSortByChar(strs, pos);
        }
    }
    
    static countingSortByChar(strs, pos) {
        const count = new Array(256).fill(0);
        for (const str of strs) {
            const ch = pos < str.length ? str.charCodeAt(pos) : 0;
            count[ch]++;
        }
        
        for (let i = 1; i < 256; i++) {
            count[i] += count[i - 1];
        }
        
        const output = new Array(strs.length);
        for (let i = strs.length - 1; i >= 0; i--) {
            const ch = pos < strs[i].length ? strs[i].charCodeAt(pos) : 0;
            output[count[ch] - 1] = strs[i];
            count[ch]--;
        }
        
        for (let i = 0; i < strs.length; i++) {
            strs[i] = output[i];
        }
    }
    
    /**
     * 方案4:基数排序优化版
     */
    static radixSortOptimized(nums) {
        if (nums.length === 0) return;
        
        const max = Math.max(...nums);
        let exp = 1;
        
        while (Math.floor(max / exp) > 0) {
            this.countingSortByDigitOptimized(nums, exp);
            exp *= 256;
        }
    }
    
    static countingSortByDigitOptimized(nums, exp) {
        const count = new Array(256).fill(0);
        for (const num of nums) {
            count[Math.floor((num / exp) % 256)]++;
        }
        
        for (let i = 1; i < 256; i++) {
            count[i] += count[i - 1];
        }
        
        const output = new Array(nums.length);
        for (let i = nums.length - 1; i >= 0; i--) {
            output[count[Math.floor((nums[i] / exp) % 256)] - 1] = nums[i];
            count[Math.floor((nums[i] / exp) % 256)]--;
        }
        
        for (let i = 0; i < nums.length; i++) {
            nums[i] = output[i];
        }
    }
    
    /**
     * 方案5:混合基数排序
     */
    static radixSortHybrid(nums) {
        if (nums.length === 0) return;
        
        const max = Math.max(...nums);
        
        if (max < 1000) {
            nums.sort((a, b) => a - b);
        } else {
            this.radixSortLSD(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();
        RadixSortJS.radixSortLSD(nums1);
        const time1 = performance.now() - start1;
        result += `方案1 - LSD基数排序: ${time1.toFixed(2)}ms\n`;
        result += '时间复杂度: O(d * (n + k))\n\n';
        
        // 方案2
        const nums2 = [...nums];
        const start2 = performance.now();
        RadixSortJS.radixSortMSD(nums2);
        const time2 = performance.now() - start2;
        result += `方案2 - MSD基数排序: ${time2.toFixed(2)}ms\n`;
        result += '时间复杂度: O(d * (n + k))\n\n';
        
        // 方案3
        const strs = Array.from({ length: 100000 }, () => 
            Math.floor(Math.random() * 1000000).toString()
        );
        const start3 = performance.now();
        RadixSortJS.radixSortString(strs);
        const time3 = performance.now() - start3;
        result += `方案3 - 字符串基数排序: ${time3.toFixed(2)}ms\n`;
        result += '时间复杂度: O(d * (n + k))\n\n';
        
        // 方案4
        const nums4 = [...nums];
        const start4 = performance.now();
        RadixSortJS.radixSortOptimized(nums4);
        const time4 = performance.now() - start4;
        result += `方案4 - 基数排序优化版: ${time4.toFixed(2)}ms\n`;
        result += '时间复杂度: O(d * (n + k))\n\n';
        
        // 方案5
        const nums5 = [...nums];
        const start5 = performance.now();
        RadixSortJS.radixSortHybrid(nums5);
        const time5 = performance.now() - start5;
        result += `方案5 - 混合基数排序(推荐): ${time5.toFixed(2)}ms\n`;
        result += '时间复杂度: O(d * (n + k))到O(n log n)\n\n';
        
        result += '性能对比总结\n';
        result += '-'.repeat(70) + '\n';
        result += '最快方案: LSD基数排序\n';
        result += '推荐方案: 混合基数排序(综合考虑性能和适应性)\n';
        
        return result;
    }
}

// 导出供Node.js使用
if (typeof module !== 'undefined' && module.exports) {
    module.exports = RadixSortJS;
}

JavaScript实现的详细说明

JavaScript版本的实现与Kotlin版本在逻辑上完全一致,但充分利用了JavaScript的语言特性。在计算数字位时,我们使用了Math.floor()。在处理字符时,我们使用了charCodeAt()来获取字符编码。

JavaScript的performance.now()方法提供了微秒级的精度,使得性能测试更加准确。在实际应用中,开发者可以使用这个性能演示函数来选择最适合的算法。

ArkTS调用实现

完整的ArkTS代码实现

/**
 * 基数排序(Radix Sort)工具 - ArkTS版本(OpenHarmony鸿蒙)
 * 用于在鸿蒙应用中实现基数排序算法
 */
import { webview } from '@kit.ArkWeb';
import { common } from '@kit.AbilityKit';

@Entry
@Component
struct RadixSortPage {
    @State inputArray: string = '170,45,75,90,2,802,24,2,66';
    @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:LSD基数排序
     */
    radixSortLSD(nums: number[]): void {
        if (nums.length === 0) return;
        
        const max = Math.max(...nums);
        let exp = 1;
        
        while (Math.floor(max / exp) > 0) {
            this.countingSortByDigit(nums, exp);
            exp *= 10;
        }
    }
    
    private countingSortByDigit(nums: number[], exp: number): void {
        const count = new Array(10).fill(0);
        for (const num of nums) {
            count[Math.floor((num / exp) % 10)]++;
        }
        
        for (let i = 1; i < 10; i++) {
            count[i] += count[i - 1];
        }
        
        const output = new Array(nums.length);
        for (let i = nums.length - 1; i >= 0; i--) {
            output[count[Math.floor((nums[i] / exp) % 10)] - 1] = nums[i];
            count[Math.floor((nums[i] / exp) % 10)]--;
        }
        
        for (let i = 0; i < nums.length; i++) {
            nums[i] = output[i];
        }
    }
    
    /**
     * 方案2:MSD基数排序
     */
    radixSortMSD(nums: number[]): void {
        if (nums.length === 0) return;
        
        const max = Math.max(...nums);
        let exp = 1;
        while (Math.floor(max / (exp * 10)) > 0) {
            exp *= 10;
        }
        
        this.radixSortMSDHelper(nums, 0, nums.length - 1, exp);
    }
    
    private radixSortMSDHelper(nums: number[], left: number, right: number, exp: number): void {
        if (left >= right || exp === 0) return;
        
        const buckets: number[][] = Array.from({ length: 10 }, () => []);
        for (let i = left; i <= right; i++) {
            buckets[Math.floor((nums[i] / exp) % 10)].push(nums[i]);
        }
        
        let idx = left;
        for (const bucket of buckets) {
            for (const num of bucket) {
                nums[idx++] = num;
            }
        }
        
        idx = left;
        for (const bucket of buckets) {
            if (bucket.length > 0) {
                this.radixSortMSDHelper(bucket, 0, bucket.length - 1, Math.floor(exp / 10));
                for (const num of bucket) {
                    nums[idx++] = num;
                }
            }
        }
    }
    
    /**
     * 方案4:基数排序优化版
     */
    radixSortOptimized(nums: number[]): void {
        if (nums.length === 0) return;
        
        const max = Math.max(...nums);
        let exp = 1;
        
        while (Math.floor(max / exp) > 0) {
            this.countingSortByDigitOptimized(nums, exp);
            exp *= 256;
        }
    }
    
    private countingSortByDigitOptimized(nums: number[], exp: number): void {
        const count = new Array(256).fill(0);
        for (const num of nums) {
            count[Math.floor((num / exp) % 256)]++;
        }
        
        for (let i = 1; i < 256; i++) {
            count[i] += count[i - 1];
        }
        
        const output = new Array(nums.length);
        for (let i = nums.length - 1; i >= 0; i--) {
            output[count[Math.floor((nums[i] / exp) % 256)] - 1] = nums[i];
            count[Math.floor((nums[i] / exp) % 256)]--;
        }
        
        for (let i = 0; i < nums.length; i++) {
            nums[i] = output[i];
        }
    }
    
    /**
     * 方案5:混合基数排序
     */
    radixSortHybrid(nums: number[]): void {
        if (nums.length === 0) return;
        
        const max = Math.max(...nums);
        
        if (max < 1000) {
            nums.sort((a, b) => a - b);
        } else {
            this.radixSortLSD(nums);
        }
    }
    
    /**
     * 执行基数排序
     */
    async executeRadixSort() {
        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 'LSD基数排序':
                    this.radixSortLSD(nums);
                    break;
                case 'MSD基数排序':
                    this.radixSortMSD(nums);
                    break;
                case '基数排序优化版':
                    this.radixSortOptimized(nums);
                    break;
                case '混合基数排序':
                    this.radixSortHybrid(nums);
                    break;
            }
            
            this.result = `排序结果: [${nums.join(', ')}]`;
            
            // 同时显示所有方法的结果
            const results = [];
            const nums1 = this.parseArray(this.inputArray);
            this.radixSortLSD(nums1);
            results.push(`LSD基数排序: [${nums1.join(', ')}]`);
            
            const nums2 = this.parseArray(this.inputArray);
            this.radixSortMSD(nums2);
            results.push(`MSD基数排序: [${nums2.join(', ')}]`);
            
            const nums4 = this.parseArray(this.inputArray);
            this.radixSortOptimized(nums4);
            results.push(`基数排序优化版: [${nums4.join(', ')}]`);
            
            const nums5 = this.parseArray(this.inputArray);
            this.radixSortHybrid(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.radixSortLSD(nums1);
            const time1 = Date.now() - start1;
            result += `方案1 - LSD基数排序: ${time1}ms\n`;
            result += '时间复杂度: O(d * (n + k))\n\n';
            
            // 方案2
            const nums2 = [...nums];
            const start2 = Date.now();
            this.radixSortMSD(nums2);
            const time2 = Date.now() - start2;
            result += `方案2 - MSD基数排序: ${time2}ms\n`;
            result += '时间复杂度: O(d * (n + k))\n\n';
            
            // 方案4
            const nums4 = [...nums];
            const start4 = Date.now();
            this.radixSortOptimized(nums4);
            const time4 = Date.now() - start4;
            result += `方案4 - 基数排序优化版: ${time4}ms\n`;
            result += '时间复杂度: O(d * (n + k))\n\n';
            
            // 方案5
            const nums5 = [...nums];
            const start5 = Date.now();
            this.radixSortHybrid(nums5);
            const time5 = Date.now() - start5;
            result += `方案5 - 混合基数排序: ${time5}ms\n`;
            result += '时间复杂度: O(d * (n + k))到O(n log n)\n\n';
            
            result += '性能对比总结\n';
            result += '-'.repeat(70) + '\n';
            result += '最快方案: LSD基数排序\n';
            result += '推荐方案: 混合基数排序(综合考虑性能和适应性)\n';
            
            this.performanceData = result;
        } catch (error) {
            this.performanceData = '演示失败:' + error;
        }
        
        this.isLoading = false;
    }
    
    build() {
        Column() {
            // 顶部栏
            Row() {
                Text('基数排序(Radix 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: 'LSD基数排序' },
                            { value: 'MSD基数排序' },
                            { 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.executeRadixSort())
                            .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. 网络数据处理

在网络数据处理中,基数排序用于IP地址和MAC地址排序。网络协议栈使用基数排序来排序网络地址。

3. 图形处理

在图形处理中,基数排序用于颜色值排序。图像处理算法使用基数排序来处理像素数据。

4. 密码学

在密码学中,基数排序用于密钥排序。密码学应用使用基数排序来处理密钥数据。

5. 科学计算

在科学计算中,基数排序用于浮点数排序。科学计算应用使用基数排序来处理数值数据。

性能优化建议

1. 选择合适的基数

对于整数排序,使用基数10。对于大整数排序,使用基数256。对于字符串排序,使用基数256。

2. 选择合适的方向

对于小范围数据,使用LSD。对于大范围数据,使用MSD。对于需要提前终止,使用MSD。

3. 使用混合排序

对于不同范围的数据,使用不同的排序方法,可以获得更好的适应性。

4. 考虑并行化

基数排序易于并行化,特别是在计数排序阶段。

总结

基数排序是一种非比较排序算法,通过按位数逐位排序来进行排序。虽然算法思想相对简单,但其实现涉及多种不同的优化策略,从LSD到MSD,再到优化版本。

通过在KMP框架下实现这个算法,我们可以在多个平台上使用同一套代码,提高开发效率。混合基数排序是解决大多数排序问题的最优方案,可以根据数据范围自动选择最优的排序方法。在OpenHarmony鸿蒙平台上,我们可以通过ArkTS调用Kotlin编译的JavaScript代码,或者直接在ArkTS中实现算法,实现真正的跨平台开发。

掌握这个经典算法的多种变体,不仅能够帮助开发者在面试中获得好成绩,更重要的是能够在实际项目中灵活应用这个算法,解决大整数排序、字符串排序等实际问题。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐