Javascrtipt 基本排序算法

冒泡排序

描述

依次比较相邻的数据,将小数据放在前,大数据放在后。即第一趟先比较第1个和第2个数,大数在后,小数在前,再比较第2个数与第3个数,大数在后,小数在前,直到将最大的数移动到最后一个位置。第二趟则将次大的数移动到倒数第二个位置,...直到将第n大的数移动到第一个输的位置,便完成排序。

实现

冒泡排序的核心操作是对两个数据进行比较和进行交换。具体做法如下(假设需要排序的数据存在一个数组变量array里面,从左往右,从小到大排序):

  1. 设置变量 i=0,j=i+1 ;

  2. 取 a=array[i] ;

  3. 从数组第j个元素开始,取 b=array[j] ;

  4. 比较 a>b ?,如果 a>b 为真,交换 a 和 b 对应数组的值,否则不做交换。继续循环, j+1 ;

  5. 当 j>=array.length 时,结束循环,否则继续 3-5 步。

  6. i=i+1 ;

  7. 重复操作 2-6 直到i>=array.length,算法结束,得到的array的值就是排序完成的数组。

/**
 * 冒泡,升序
 * @param  {array} array  数值数组
 * @return {array}        排好序的数据,不该变原数组
 */
function bubbleSort (array) {
    let tempArray = [].concat(array)
    let i = 0;
    let j = 0;
    let len = tempArray.length
    for (i = 0; i < len; i++) {
      for (j = i + 1; j < len; j++) {
        let a = tempArray[i];
        let b = tempArray[j];
        if (a > b) {
          tempArray[i] = b;
          tempArray[j] = a;
        }
      }
    }
    return tempArray;
}

bubbleSort([9,8,7,6,5,4,3,2,1]);

视频演示:http://v.youku.com/v_show/id_XMzMyOTAyMzQ0.html

总结

 冒泡排序的核心操作是比较和数据交换.时间复杂为O(n^2),是稳定的排序算法,但是效率并不高。


选择排序

选择排序可以看作是冒泡排序的一种优化。在冒泡排序的过程中,会做许多无用的数据交换,因为在冒泡排序里,交换数据只能保证当前两个数据的正确排序位置,但很可能不是最后的排序位置。也就是说,之后这个两个数据可能还需要和其其它数据交换位置,才能得到最后的结果。这样就会产生许多无用的数据交换操作,这也是冒泡排序效率不高的一个原因。选择排序集针对这一点做了优化,他依然想冒泡排序那样比较数据,不同之处在于,在满足数据交换的条件时,并不立即进行数据交换的操作,而是记录该数据的位置,当该数据与所有的数据比较完成后,最后在进行数据交换的操作。

描述

选择排序从数组的开头开始,将第一个元素和其他元素进行比较。检查完所有元素后,最小的元素会被放到数组的第一个位置,然后算法会从第二个位置继续。这个过程一直进行,当进行到数组的倒数第二个位置时,所有的数据便完成了排序。

实现

具体实现过程如下((假设需要排序的数据存在一个数组变量array里面,左往右,从小到大排序):

  1. 设置变量 i=0 ;

  2. 取 temp=i,j=i;

  3. 从数组元素第j个元素开始循环。

  4. 比较 array[temp]>array[j] ? ,若 array[temp]>array[j] 为真,那么 temp=j,j=j+1 ;

  5. 如果 j>=array.length ,则结束循环,否则继续执行 4-5 ;

  6. 交换数组元素 array[i] 和 array[temp] 的值, i=i+1 ;

  7. 如果 i>=array.length ,则结束循环,得到的数据就是完成排序的数组,否则继续执行 2-6 步;

function chooseSort(array) {
    var temp = -1;
    for (var i = 0; i < array.length; i++) {
        //寻找i以及i元素之后,最小的数组元素
        temp = i;
        for (var j = i; j < array.length; j++) {
            if (array[temp] > array[j]) {
                temp = j;
            }
        }
        //每次内存循环最多交换一次
        if (temp != j) {
            var tempData = array[i];
            array[i] = array[temp];
            array[temp] = tempData;
        }
    }
    return array;
}

视频演示:http://v.youku.com/v_show/id_XMzMyODk5MDI0.html

总结

选择排序的效率会比冒泡的效率高(在排序的数据量非常大的情况下),因为他减少了许多无用的数据交换操作,而数据交换操作相对于数据比较操作是很耗时的。选择排序的时间复杂度为O(n^2),算法是稳定的。


插入排序

描述

插入排序有两个循环。外循环将数组元素挨个移动,而内循环则对外循环中选中的元素及它后面的那个元素进行比较。如果外循环中选中的元素比内循环中选中的元素小,那么数组元素会向右移动,为内循环中的这个元素腾出位置。

实现

  1. 从第一个元素开始,该元素可以认为已经被排序

  2. 取出下一个元素,在已经排序的元素序列中从后向前扫描

  3. 如果该元素(已排序)大于新元素,将该元素移到该元素的下一位置

  4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置

  5. 将新元素插入到该位置后

  6. 重复步骤2~5

function insertOrder(array) {
    var len = array.length;

    for (var i = 1; i < len; i++) {
        var temp = array[i],
            j = i;

        while (j > 0 && array[j - 1] > temp) {
            array[j] = array[j - 1];
            j--;
        }

        array[j] = temp;
    }

    return array;
}

视频演示:http://v.youku.com/v_show/id_XMjU4NTY5MzEy.html

结论

插入排序的时间复杂度为O(n^2),算法是稳定的。

原文地址:https://www.cnblogs.com/hlere/p/6813209.html