基础算法进修之(二)疾速排序与合并排序

疾速排序(Quick Sort)

看名字知特性,就是快,效率高.它是处置惩罚大数据最快的排序算法之一.
巧妙的影象点:

  • 内排序

  • 不稳定

基本思想

经由过程一趟排序把待排序纪录分为自力的两部份,个中一部份纪录的关键字都比另一部份的关键字笑,则分别对两部份继续举行排序,以到达全部序列有序.
本身的明白:
实在就是用分治法的思绪,将一个数组分为两半,举行无线支解排序.
首先在数列中取一个值,成为”关键字/基准”(pivot);
然后比它小的放前面,大的放背面,雷同的话随意放.
递归的把我们分为两半的数组再次分半排序.

疾速排序(代码)

//要领一
function quickSort(array, left, right) {//传入参数为数组,left,right为排序地区下标
    console.time('1.疾速排序耗时');
    if (Object.prototype.toString.call(array).slice(8, -1) === 'Array' && typeof left === 'number' && typeof right === 'number') {//推断传入参数的正确性
        if (left < right) { //正确性推断
            var x = array[right], i = left - 1, temp;//x变量为待排序数组末端
            for (var j = left; j <= right; j++) {    //从左到右
                if (array[j] <= x) {
                    i++;//注重i先增在交流
                    temp = array[i];
                    array[i] = array[j];
                    array[j] = temp;
                }
            }
            quickSort(array, left, i - 1);
            quickSort(array, i + 1, right);
        }
        console.timeEnd('1.疾速排序耗时');
        return array;
    } else {
        return 'array is not an Array or left or right is not a number!';
    }
}

//要领二
var quickSort2 = function(arr) {
    console.time('2.疾速排序耗时');
  if (arr.length <= 1) { return arr; }
  var pivotIndex = Math.floor(arr.length / 2);
  var pivot = arr.splice(pivotIndex, 1)[0];
  var left = [];
  var right = [];
  for (var i = 0; i < arr.length; i++){
    if (arr[i] < pivot) {
      left.push(arr[i]);
    } else {
      right.push(arr[i]);
    }
  }
console.timeEnd('2.疾速排序耗时');
  return quickSort2(left).concat([pivot], quickSort2(right));
};

var arr=[3,49,38,5,47,15,36,26,27,2,46,4,19,50,48];
console.log(quickSort(arr,0,arr.length-1));//[2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]
console.log(quickSort2(arr));//[2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]


影象点
  • best condition: T(n) = O(nlog n)

  • baddest condition: T(n) = O(n^2)

  • average condition: T(n) = O(nlog n)

兼并排序(Merge Sort)

不受输入数据影响,然则表现比挑选排序好.价值是须要分外的内存空间.
巧妙的影象点:

  • 外排序(须要分外的内存空间)

  • 稳定的排序算法(排序后元素原始递次不会变化)

基本思想:

分治法(Divide and Conquer)

将已有序的子序列兼并,从而获得完整有序的序列.也称为2-路兼并.

兼并排序:代码

function mergeSort(arr) {  //采纳自上而下的递归要领
    var len = arr.length; //猎取传入数组的长度
    if(len < 2) {   //假如为单个元素则直接返回
        return arr;
    }
    var middle = Math.floor(len / 2),//取中点
        left = arr.slice(0, middle), //取左侧区间
        right = arr.slice(middle);   //取右侧区间
    return merge(mergeSort(left), mergeSort(right));//挪用兼并函数
}

function merge(left, right)//传入两个区间
{
    var result = [];//新建变量用于保留效果
    console.time('兼并排序耗时');
    while (left.length && right.length) { //当左区间右区间存在时
        if (left[0] <= right[0]) {  //将区间中较小的一名从区间数组中放到效果数组中.
            result.push(left.shift());
        } else {
            result.push(right.shift());
        }
    }
    //下面两个while是为了处理遗留元素题目
    while (left.length) 
        result.push(left.shift());

    while (right.length)
        result.push(right.shift());
    console.timeEnd('兼并排序耗时');
    return result;//返回效果
}
var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
console.log(mergeSort(arr));
/*10次兼并
兼并排序耗时: 0ms
兼并排序耗时: 0ms
兼并排序耗时: 0ms
兼并排序耗时: 0ms
兼并排序耗时: 0ms
兼并排序耗时: 0ms
兼并排序耗时: 0ms
兼并排序耗时: 0ms
兼并排序耗时: 0ms
兼并排序耗时: 0ms
[ 2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50 ]      */
影象点
  • best condition: T(n) = O(n)

  • baddest condition: T(n) = O(nlog n)

  • average condition: T(n) = O(nlog n)

    原文作者:thewindsword
    原文地址: https://segmentfault.com/a/1190000006987087
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞