JS实现希尔排序、归并排序

希尔排序

希尔排序的基本思想是:把序列按一定增量分组,然后对每个分组使用插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。

  • 希尔排序是插入排序的改进版本。
  • 插入排序的问题在于当数组长度扩大时,后面的元素插入时要检查前面n个元素,非常影响排序性能。
        function shellSort(arr) {
            let length = arr.length;
            let interval = Math.floor(length / 2);
            //需要循环次数
            while (interval >= 1) {
                //循环体为插入排序算法
                for (let i = interval; i < length; i++) {
                    //从interval开始往后依次排序
                    let temp = arr[i];
                    let j = i;
                    while (temp < arr[j - interval] && j - interval >= 0) {
                        arr[j] = arr[j - interval];
                        //步进表达式
                        j -= interval;
                    }
                    arr[j] = temp;//移动法
                }

                //步进表达式
                interval = Math.floor(interval / 2);
            }
            return arr;
        }
归并排序

归并排序使用了分治的思想。

  • 归:把数组分成两半,再递归地对子数组进行分操作,直到分成一个个单独的数
  • 并:把两个数合并为有序数组,再对有序数组进行合并,直到全部子数组合并为一个完整数组
 function mergeSort(arr) {
            console.log(main(arr));

            function main(arr) {
                //在数组分解为单个元素后返回,防止无限递归导致callstack溢出
                if (arr.length === 1) return arr;
                //分解数组,递归下可分成单个元素
                let mid = Math.floor(arr.length / 2);
                let left = arr.slice(0, mid);
                let right = arr.slice(mid);

                //分解完后合并

                //arguments对象里的callee属性是指向arguments对象所在函数的指针
                //arguments.callee(left) == main(left)
                return merge(arguments.callee(left), arguments.callee(right));
            }

            //合并函数
            function merge(left, right) {
                let il = 0;
                let rl = 0;
                let result = [];
                //同时遍历左右两个数组,直到有一个指针超出范围
                while (il < left.length && rl < right.length) {
                    if (left[il] < right[rl]) {
                        result.push(left[il++]);
                    } else {
                        result.push(right[rl++]);
                    }
                }
                return result.concat(left.slice(il)).concat(right.slice(rl));
            }
        }

        var arr = [8, 7, 6, 5, 4, 3, 2, 1, 10, 9];
        var a = mergeSort(arr);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值