【排序算法】冒泡 选排 插排 快排 归并

一、冒泡排序

javascript 复制代码
// 冒泡排序

var bubbleSort = function (arr) {
    const len = arr.length;
    for (let i = 0; i < len; i++) {
        let isSwap = false;
        for (let j = 0; j < len - 1; j++) {
            // 每一次遍历都要比较相邻元素的大小,如果满足条件就交换位置
            if (arr[j] > arr[j + 1]) {
                [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
                isSwap = true;
            }
        }
        // 如果遍历完数组后没有发生交换,说明已经排序好了,跳出循环,中断剩余操作
        if (!isSwap) {
            break;
        }
    }
    return arr;
}

console.log(bubbleSort([7, 3, 2, 21, 12, 1, 4, 9, 10]));

二、选择排序

javascript 复制代码
// 选择排序

var selectionSort = function (arr) {
    const len = arr.length;
    // 外循环的 i 指向需要替换的位置,而 i 之前是已经排序的数组
    for (let i = 0; i < len - 1; i++) {
        let minIndex = i;
        // 内循环是在未排序好的数组中找最小值的索引
        for (let j = i + 1; j < len; j++) {
            if (arr[minIndex] > arr[j]) {
                minIndex = j;
            }
        }
        // 找到最小值的索引后交换位置即可
        [arr[i], arr[minIndex]] = [arr[minIndex], arr[i]];
    }
    return arr;
}

console.log(selectionSort([7, 3, 2, 21, 12, 1, 4, 9, 10]));

三、插入排序

javascript 复制代码
// 插入排序

var insertionSort = function (arr) {
    const len = arr.length;
    for (let i = 1; i < len; i++) {
        base = arr[i]; // 将未排序数组中的第一个元素作为基数
        let j = i - 1; // j 指向已排序好的数组的最后一个元素
        while (j >= 0 && arr[j] > base) {
            arr[j + 1] = arr[j]; // 如果以上满足条件,元素 arr[j] 后移一位
            j--; // 向前遍历
        }
        // 因为 j 在最后一次循环中减了一次,此时 j + 1 之后的元素都小于 base,所以 base 要插入的正确的位置是 j + 1
        arr[j + 1] = base;
    }
    return arr;
}

console.log(insertionSort([7, 3, 2, 21, 12, 1, 4, 9, 10]));

四、快速排序

javascript 复制代码
// 快速排序 O(n log n)

// 分治
var partition = function (arr, left, right) {
    let i = left, j = right;
    let base = arr[left]; // 每次将 arr[left] 作为基数
    while (i < j) {
        // 在右边数组找比基数小的数的索引
        while (i < j && arr[j] >= base) {
            j--;
        }
        while (i < j && arr[i] <= base) {
            i++;
        }
        // 交换位置
        [arr[i], arr[j]] = [arr[j], arr[i]];
    }
    // 此时 i 索引指向的就是基数应该处于的位置
    [arr[i], arr[left]] = [arr[left], arr[i]];
    console.log("arr:", arr);
    return i;
}

// 递归
var quickSort = function (arr, left, right) {
    // 递归终止条件
    if (left >= right) {
        return;
    }
    // 递归操作

    // 找到基数所在的索引作为中间支点
    let pivot = partition(arr, left, right);
    // 左递归
    quickSort(arr, left, pivot - 1);
    // 右递归
    quickSort(arr, pivot + 1, right);
}
let arr = [7, 3, 2, 21, 12, 1, 4, 9, 10, 31, 64, 108, 13, 5];
let len = arr.length - 1;
quickSort(arr, 0, len);

五、归并排序

javascript 复制代码
// 归并排序

var mergeSort = function (arr) {
    // 递归终止条件
    if (arr.length <= 1) {
        return arr;
    }

    // 递归操作
    const mid = arr.length / 2;
    // 拆分数组
    const leftArr = mergeSort(arr.slice(0, mid));
    const rightArr = mergeSort(arr.slice(mid));
    return merge(leftArr, rightArr);
}

// 归并操作
var merge = function (leftArr, rightArr) {
    let left = 0, right = 0;
    let ans = [];
    // 按需归并
    while (left < leftArr.length && right < rightArr.length) {
        if (leftArr[left] <= rightArr[right]) {
            ans.push(leftArr[left]);
            left++;
        } else {
            ans.push(rightArr[right]);
            right++;
        }
    }
    // 剩余元素直接追加
    return ans.concat(leftArr.slice(left)).concat(rightArr.slice(right));
}

// ======== 测试 ========
const arr = [7, 3, 2, 21, 12, 1, 4, 9, 10, 108, 24, 35, 5, 8, 124];
console.log('排序后:', mergeSort(arr));
console.log('原数组是否改变:', arr);  // 保持不变
相关推荐
海上小飞龙2 小时前
【KMP算法-下篇】同一道题:Java 库函数 2600 微秒,手写 KMP 16 微秒
java·开发语言·算法
青少儿编程课堂3 小时前
后缀自动机解析:本质不同子串与最长重复片段统计
c++·python·算法·bfs·信息学竞赛
朝朝辞暮i3 小时前
C++ 第 12 课:局部变量、作用域、变量生命周期
开发语言·c++·算法
乐迪信息4 小时前
港口船舶逆行怎么管?AI防爆摄像机搭载智能检测算法
大数据·人工智能·深度学习·算法·计算机视觉
Sirens.5 小时前
Java并发锁详解:六类锁策略与 synchronized 底层原理
java·前端·算法
和裕5 小时前
全纸结构重型纸箱能否满足 1 吨以上设备出口熏蒸豁免要求?通关合规性全解析
大数据·运维·网络·人工智能·算法
tangguofeng6 小时前
不带头结点的链队操作集(不含InitFlag)(C语言版)
算法
苏打豆7 小时前
CRISP源码阅读——基于ROS2力矩反馈控制器与速度加速度零空间
c++·线性代数·算法·矩阵·机器人
蛋蛋的就会顺顺的8 小时前
hot100——矩阵
java·数据结构·算法·leetcode·力扣
老歌老听老掉牙8 小时前
麻花钻切屑形态演变的力学机制与临界条件分析
python·算法·钻头