排序算法 (Sorting Algorithms)-JS示例

基本概念

排序算法是将一组数据按照特定顺序(通常是升序或降序)重新排列的算法。它是计算机科学中最基础也是最重要的算法之一。

核心特性

  • 稳定性:相等元素在排序后的相对位置不变
  • 时间复杂度:算法执行所需的时间
  • 空间复杂度:算法执行所需的额外存储空间
  • 原地排序:只需要常数级额外空间的排序算法

常见分类

  1. 比较排序:通过比较元素大小来决定顺序(如冒泡排序、快速排序)
  2. 非比较排序:不通过比较元素大小(如计数排序、桶排序)

经典排序算法 JS 示例

1. 冒泡排序 (Bubble Sort)

javascript 复制代码
function bubbleSort(arr) {
    const n = arr.length;
    // 创建数组副本以避免修改原数组
    const result = [...arr];
    
    for (let i = 0; i < n - 1; i++) {
        let swapped = false;
        // 每轮将最大元素"冒泡"到末尾
        for (let j = 0; j < n - i - 1; j++) {
            if (result[j] > result[j + 1]) {
                // 交换元素
                [result[j], result[j + 1]] = [result[j + 1], result[j]];
                swapped = true;
            }
        }
        // 如果没有发生交换,说明数组已经有序
        if (!swapped) break;
    }
    
    return result;
}

// 示例使用
const arr1 = [64, 34, 25, 12, 22, 11, 90];
console.log('原数组:', arr1);
console.log('冒泡排序结果:', bubbleSort(arr1));

2. 选择排序 (Selection Sort)

javascript 复制代码
function selectionSort(arr) {
    const n = arr.length;
    const result = [...arr];
    
    for (let i = 0; i < n - 1; i++) {
        // 找到未排序部分的最小元素索引
        let minIndex = i;
        for (let j = i + 1; j < n; j++) {
            if (result[j] < result[minIndex]) {
                minIndex = j;
            }
        }
        // 将最小元素与未排序部分的第一个元素交换
        if (minIndex !== i) {
            [result[i], result[minIndex]] = [result[minIndex], result[i]];
        }
    }
    
    return result;
}

// 示例使用
const arr2 = [64, 34, 25, 12, 22, 11, 90];
console.log('原数组:', arr2);
console.log('选择排序结果:', selectionSort(arr2));

3. 插入排序 (Insertion Sort)

javascript 复制代码
function insertionSort(arr) {
    const result = [...arr];
    
    for (let i = 1; i < result.length; i++) {
        const key = result[i];
        let j = i - 1;
        
        // 将大于key的元素向右移动
        while (j >= 0 && result[j] > key) {
            result[j + 1] = result[j];
            j--;
        }
        result[j + 1] = key;
    }
    
    return result;
}

// 示例使用
const arr3 = [64, 34, 25, 12, 22, 11, 90];
console.log('原数组:', arr3);
console.log('插入排序结果:', insertionSort(arr3));

4. 快速排序 (Quick Sort)

javascript 复制代码
function quickSort(arr) {
    if (arr.length <= 1) {
        return arr;
    }
    
    const pivot = arr[Math.floor(arr.length / 2)];
    const left = [];
    const right = [];
    const equal = [];
    
    for (let element of arr) {
        if (element < pivot) {
            left.push(element);
        } else if (element > pivot) {
            right.push(element);
        } else {
            equal.push(element);
        }
    }
    
    return [...quickSort(left), ...equal, ...quickSort(right)];
}

// 原地快速排序版本
function quickSortInPlace(arr, low = 0, high = arr.length - 1) {
    if (low < high) {
        const pi = partition(arr, low, high);
        quickSortInPlace(arr, low, pi - 1);
        quickSortInPlace(arr, pi + 1, high);
    }
    return arr;
}

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;
}

// 示例使用
const arr4 = [64, 34, 25, 12, 22, 11, 90];
console.log('原数组:', arr4);
console.log('快速排序结果:', quickSort([...arr4]));

5. 归并排序 (Merge Sort)

javascript 复制代码
function mergeSort(arr) {
    if (arr.length <= 1) {
        return arr;
    }
    
    const mid = Math.floor(arr.length / 2);
    const left = mergeSort(arr.slice(0, mid));
    const right = mergeSort(arr.slice(mid));
    
    return merge(left, right);
}

function merge(left, right) {
    const result = [];
    let leftIndex = 0;
    let rightIndex = 0;
    
    // 合并两个已排序的数组
    while (leftIndex < left.length && rightIndex < right.length) {
        if (left[leftIndex] < right[rightIndex]) {
            result.push(left[leftIndex]);
            leftIndex++;
        } else {
            result.push(right[rightIndex]);
            rightIndex++;
        }
    }
    
    // 添加剩余元素
    return result.concat(left.slice(leftIndex)).concat(right.slice(rightIndex));
}

// 示例使用
const arr5 = [64, 34, 25, 12, 22, 11, 90];
console.log('原数组:', arr5);
console.log('归并排序结果:', mergeSort(arr5));

6. 堆排序 (Heap Sort)

javascript 复制代码
function heapSort(arr) {
    const result = [...arr];
    const n = result.length;
    
    // 构建最大堆
    for (let i = Math.floor(n / 2) - 1; i >= 0; i--) {
        heapify(result, n, i);
    }
    
    // 逐个提取元素
    for (let i = n - 1; i > 0; i--) {
        [result[0], result[i]] = [result[i], result[0]]; // 将当前最大元素移到末尾
        heapify(result, i, 0); // 重新调整堆
    }
    
    return result;
}

function heapify(arr, n, i) {
    let largest = i;
    const left = 2 * i + 1;
    const right = 2 * i + 2;
    
    if (left < n && arr[left] > arr[largest]) {
        largest = left;
    }
    
    if (right < n && arr[right] > arr[largest]) {
        largest = right;
    }
    
    if (largest !== i) {
        [arr[i], arr[largest]] = [arr[largest], arr[i]];
        heapify(arr, n, largest);
    }
}

// 示例使用
const arr6 = [64, 34, 25, 12, 22, 11, 90];
console.log('原数组:', arr6);
console.log('堆排序结果:', heapSort(arr6));
相关推荐
前端开发爱好者23 分钟前
只有 7 KB!前端圈疯传的 Vue3 转场动效神库!效果炸裂!
前端·javascript·vue.js
Fly-ping34 分钟前
【前端】JavaScript文件压缩指南
开发语言·前端·javascript
YouQian77239 分钟前
(AC)Playlist
算法
算法_小学生1 小时前
决策树(Decision Tree)完整解析:原理 + 数学推导 + 剪枝 + 实战
算法·决策树·剪枝
接口写好了吗1 小时前
【el-table滚动事件】el-table表格滚动时,获取可视窗口内的行数据
javascript·vue.js·elementui·可视窗口滚动
岁忧1 小时前
(LeetCode 面试经典 150 题 ) 155. 最小栈 (栈)
java·c++·算法·leetcode·面试·go
未来之窗软件服务2 小时前
免费版酒店押金原路退回系统之【房费押金计算器】实践——仙盟创梦IDE
前端·javascript·css·仙盟创梦ide·东方仙盟·酒店押金系统
明明如月学长3 小时前
什么你不知道 Cherry Studio 有快捷助手?
算法
云边散步3 小时前
《校园生活平台从 0 到 1 的搭建》第四篇:微信授权登录前端
前端·javascript·后端
讨厌吃蛋黄酥3 小时前
React样式冲突终结者:CSS模块化+Vite全链路实战指南🔥
前端·javascript·react.js