/** * 快速排序算法实现 * 时间复杂度: 平均 O(n log n), 最坏 O(n²) * 空间复杂度: O(log n) */ /** * 快速排序主函数 * @param {Array} arr - 要排序的数组 * @returns {Array} - 排序后的数组 */ function quickSort(arr) { // 如果数组长度小于等于1,直接返回 if (arr.length <= 1) { return arr; } // 选择基准值(这里选择最后一个元素) const pivot = arr[arr.length - 1]; const left = []; const right = []; // 将数组分成两部分 for (let i = 0; i < arr.length - 1; i++) { if (arr[i] <= pivot) { left.push(arr[i]); } else { right.push(arr[i]); } } // 递归排序左右两部分,并合并结果 return [...quickSort(left), pivot, ...quickSort(right)]; } /** * 原地快速排序(优化版本,节省空间) * @param {Array} arr - 要排序的数组 * @param {number} low - 起始索引 * @param {number} high - 结束索引 */ function quickSortInPlace(arr, low = 0, high = arr.length - 1) { if (low < high) { const pivotIndex = partition(arr, low, high); quickSortInPlace(arr, low, pivotIndex - 1); quickSortInPlace(arr, pivotIndex + 1, high); } return arr; } /** * 分区函数 * @param {Array} arr - 数组 * @param {number} low - 起始索引 * @param {number} high - 结束索引 * @returns {number} - 基准值的最终位置 */ function partition(arr, low, high) { // 选择最后一个元素作为基准值 const pivot = arr[high]; let i = low - 1; // 小于基准值的元素的最后位置 for (let j = low; j < high; j++) { // 如果当前元素小于等于基准值 if (arr[j] <= pivot) { i++; // 交换元素 [arr[i], arr[j]] = [arr[j], arr[i]]; } } // 将基准值放到正确的位置 [arr[i + 1], arr[high]] = [arr[high], arr[i + 1]]; return i + 1; } /** * 三路快速排序(处理重复元素较多的数组) * @param {Array} arr - 要排序的数组 * @param {number} low - 起始索引 * @param {number} high - 结束索引 */ function quickSortThreeWay(arr, low = 0, high = arr.length - 1) { if (low < high) { const [lt, gt] = partitionThreeWay(arr, low, high); quickSortThreeWay(arr, low, lt - 1); quickSortThreeWay(arr, gt + 1, high); } return arr; } /** * 三路分区函数 * @param {Array} arr - 数组 * @param {number} low - 起始索引 * @param {number} high - 结束索引 * @returns {Array} - [lt, gt] 小于和大于基准值的边界 */ function partitionThreeWay(arr, low, high) { const pivot = arr[low]; let lt = low; // 小于基准值的右边界 let gt = high; // 大于基准值的左边界 let i = low + 1; // 当前扫描位置 while (i <= gt) { if (arr[i] < pivot) { [arr[lt], arr[i]] = [arr[i], arr[lt]]; lt++; i++; } else if (arr[i] > pivot) { [arr[gt], arr[i]] = [arr[i], arr[gt]]; gt--; } else { i++; } } return [lt, gt]; } // 测试函数 function testQuickSort() { console.log("=== 快速排序算法测试 ==="); // 测试数据 const testCases = [ [64, 34, 25, 12, 22, 11, 90], [5, 2, 4, 6, 1, 3], [1], [], [3, 3, 3, 3, 3], [9, 8, 7, 6, 5, 4, 3, 2, 1], [1, 2, 3, 4, 5, 6, 7, 8, 9] ]; testCases.forEach((testCase, index) => { console.log(`\n测试用例 ${index + 1}:`); console.log(`原始数组: [${testCase}]`); // 测试标准快速排序 const sorted1 = quickSort([...testCase]); console.log(`标准快排: [${sorted1}]`); // 测试原地快速排序 const arr2 = [...testCase]; quickSortInPlace(arr2); console.log(`原地快排: [${arr2}]`); // 测试三路快速排序 const arr3 = [...testCase]; quickSortThreeWay(arr3); console.log(`三路快排: [${arr3}]`); }); } // 导出函数供其他模块使用 if (typeof module !== 'undefined' && module.exports) { module.exports = { quickSort, quickSortInPlace, quickSortThreeWay, partition, partitionThreeWay }; } // 如果直接在浏览器中运行,执行测试 if (typeof window !== 'undefined') { // 将函数添加到全局作用域 window.quickSort = quickSort; window.quickSortInPlace = quickSortInPlace; window.quickSortThreeWay = quickSortThreeWay; // 自动运行测试 testQuickSort(); }