冒泡排序

冒泡排序可能是我们接触的第一个排序算法了,比较简单也实用。

思路:依次比较相邻的两个元素,值大的就换到右边,一趟循环下来最右边就是最大的元素了。然后再从头开始,找第二大的元素,这样一直走下来,整个数组就有序了。

可以参考以下gif图,理解冒泡排序的思想。

那么N个数字要排序完成,总共进行N-1趟排序,每i趟的排序次数为(N-i)次,所以需要比较的次数就是[n(n-1)]/2,即时间复杂度为 O(n^2)

直接上代码:

var bubbleSort = function(array){            //冒泡排序
    var length = array.length
    for (var i = 0; i < length; i++) {
        for (var j = 0; j < length-1-i; j++) {
            if (array[j] > array[j+1]) {
                swap(array, j, j+1);
            }
        }
    }
}

var swap = function(array, index1, index2){        //交换两个元素的位置
    var aux = array[index1];
    array[index1] = array[index2];
    array[index2] = aux;
}
var createNonSortedArray =function(size){        //创建一个size大小的无序列表ArrayList
    var array = new Array();
    for (var i = size; i > 0; i--) {
        array.push( parseInt(Math.random()*10000));
    }
    return array;
}

var arr = createNonSortedArray(10000);
bubbleSort(arr);

这个代码无论是最好的情况(数组有序),还是最坏情况(数组逆序),需要比较的次数都是[n(n-1)]/2,也就是时间复杂度均为 O(n^2),但如果是最好的情况,一趟比较下来发现没有元素要交换,那么时间复杂度就能降到 O(n),故再加一个标志位,就能让冒泡排序的最好情况时间复杂度降到 O(n),如下:

var bubbleSort = function(array){
    var length = array.length,
    for (var i = 0; i < length; i++) {
        var didSwap = false;            //设置标志位
        for (var j = 0; j < length-1-i; j++) {
            if (array[j] > array[j+1]) {
                swap(array, j, j+1);
                didSwap = true;
            }
        }
        if(!didSwap) break;                //没有交换了,直接跳出循环
    }
}

插入排序

思想:一个元素就是有序的,那么从第二个元素开始,与它之前的元素作比较,如果比之前的元素小,就交换位置。直到比某个元素大,就结束此次循环,也就找到了该元素应该在的位置了。把所有元素都走一遍,整个数组就有序了。

可以参考以下gif图,理解插入排序的思想。

在插入排序中,当待排序数组是有序时,是最优的情况,只需当前数跟前一个数比较一下就可以了,这时一共需要比较N-1次,时间复杂度为 O(n)。

最坏的情况是待排序数组是逆序的,此时需要比较次数最多,总次数记为:1+2+3+…+N-1,所以,插入排序最坏情况下的时间复杂度为 O(n^2)。

var insertionSort = function(array){
    var length = array.length,
        temp, j;
        for(var i = 1; i<length; i++){
        j = i;
        temp = array[i];
        while(j > 0 && array[j-1] > temp){
            array[j] = array[j-1];
            j--;
        }
        array[j] = temp;
    }
}

选择排序

思想:从数组的第一个元素开始,一趟循环,找出最小的,放到第一个元素的位置,然后从第二个元素开始,重复之前的步骤,直到数组整个有序。

可以参考以下gif图,理解选择排序的思想。
其中橙色表示当前排序趟的最左侧元素,绿色是这趟排序找到的最小元素的位置,灰背景是当前比较的指针。

时间复杂度其实与冒泡排序类似,也是一个 O(n^2)复杂度的算法。
代码如下:

var selectionSort = function(array){
    var length = array.length,
        indexMin;
    for (var i = 0; i < length-1; i++) {
        indexMin = i;
        for(var j = i;j<length;j++){
          if(array[indexMin] > array[j]){
            indexMin = j;
          }
        }
        if(i != indexMin){
          swap(array, i, indexMin)        //与之前冒泡排序swap方法一致,交换元素位置
        }
    }
}

这个少年有点热丶
363 声望12 粉丝

[链接]