十大排序算法之归并排序

200 阅读1分钟

20170126232807_XcivA.jpeg 归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

作为一种典型的分而治之思想的算法应用,归并排序的实现由两种方法:

  • 自上而下的递归
  • 自下而上的迭代;

算法步骤

  1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;
  2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置;
  3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;
  4. 重复步骤 3 直到某一指针达到序列尾;
  5. 将另一序列剩下的所有元素直接复制到合并序列尾。

image.png

复杂度

标题数据
平均时间复杂度O(nlogn)
最好情况O(nlogn)
最坏情况O(nlogn)
空间复杂度O(n)
排序方式Out-place
稳定性稳定

代码演示

    function mergeSort(list) {
            function Sort(list, start, end) {
                if (start >= end) return;
                //选择中位值开始递归
                let mid = (start + end) / 2 | 0;
                Sort(list, start, mid);
                Sort(list, mid + 1, end);

                let temp = [],//归位数组
                    index = 0,//归位初始化下边
                    p1 = start,//左边的初始指针
                    p2 = mid + 1;//右边的初始指针
                //并-左右两边还有剩余元素,进行比较归位
                while (p1 <= mid || p2 <= end) {
                    //右边为空时或者左右边都有值但是左边小
                    if (p2 > end || p1 <= mid && list[p1] < list[p2]) {
                        //左边并进去
                        temp[index++] = list[p1++]
                    } else {
                        //右边并进去
                        temp[index++] = list[p2++]
                    }
                }
                //并-合并成原来的数组
                for (let i = start; i <= end; i++) {
                    //通过减去start找到归位点
                    list[i] = temp[i - start]
                }
                return list
            }

            return Sort(list, 0, list.length - 1)
        }

过程输出

image.png

结果

image.png