JS-快速排序和归并排序

一:归并排序;

核心思路:

不断的折半拆分,以 数组长度 / 2 为数组中间值拆分为左侧数组和右侧数组。

不断递归继续拆分已经拆分出来的左侧数组和右侧数组

直到满足递归结束条件:拆分出来的数组的长度为 1。

让每次递归结束返回的数组是有序的:

设置临时数组,比较左右侧数组首元素的大小,较小的首元素移除数组推入到临时数组当中。

改变原数组。

// 1.折半拆分数组--直到把数组每个元素都单独抽离拆分出来
// 2.对拆分出来的俩个单独的数组元素进行排序,合并成一个有序小数组
// 递归以上步骤,直到将所有单独数组元素合并成一个数组
Array.prototype.mergeSort = function () {
    // 递归函数
    const rec = (arr) => {
        // 递归结束条件:拆分成单独数组时递归结束
        if (arr.length === 1) return arr;
        // 折半拆分
        const mid = Math.floor(arr.length / 2);
        // 拆分的左侧数组
        const left = arr.slice(0, mid);
        // 拆分的右侧数组
        const right = arr.slice(mid, arr.length);
        // 递归继续拆分
        const orderLeft = rec(left);
        const orderRight = rec(right);
        // 将拆分的单个数组元素进行排序
        const res = [];
        while (orderLeft.length || orderRight.length) {
            if (orderLeft.length && orderRight.length) {
                // 犯错的点:
                // 推入左拆分数组或者右拆分数组的头元素,同时是要删除掉数组头元素的
                // 因为这俩个左右拆分数组是要不断循环最后合并成一个顺序数组的
                res.push(orderLeft[0] < orderRight[0] ? orderLeft.shift() : orderRight.shift());
            } else if (orderLeft.length) {
                res.push(orderLeft.shift());
            } else if (orderRight.length) {
                res.push(orderRight.shift());
            }
        }
        return res;
    }
    rec(this).forEach((n, i) => {
        this[i] = n;
    })
}
const arr = [5,4,38,8,1,2,2,1];
arr.mergeSort();
console.log(arr);

二:快速排序

随便以数组的某一个元素为基准(方便起见所以以数组第一个元素为基准),比基准元素小的加入到新左侧数组当中,比基准元素大的加入到新右侧数组当中。

不断让新左侧数组和右侧数组递归以上方法,每次都要将 左侧数组 基准值 右侧数组 拼接成一个数组。

Array.prototype.quickSort = function () {
    const rec = (arr) => {
        // 递归结束条件
        if(arr.length <= 1) return arr;
        // 以随机选定的数组的某一个元素为基准,划分左右区间
        const left = [];
        const right = [];
        // 选取数组第一个为基准
        const mid = arr[0];
        // 根据基准划分左右区间
        for (let i = 1; i < arr.length; i++) {
            if (mid > arr[i]) {
                left.push(arr[i]);
            } else {
                right.push(arr[i]);
            }
        }
        // 递归调用并进行数组拼接
        return [...rec(left), mid, ...rec(right)];
    }
    const res = rec(this);
    // 改变原数组
    res.forEach((n, i) => {
        this[i] = n;
    })
}
//const arr = [2,4,5,3,1]
const arr = [8,2,4,5,3,1,1,11,8,22];   // l:2 4 5 4 1 1; m:8; r: 11 8 22 
arr.quickSort();
console.log(arr);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值