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);
经验分享 程序员 微信小程序 职场和发展