简单排序总结

冒泡排序:
基本思想:两辆比较相邻记录的关键字,如果反序则交换,直到没有反序的记录位置。比如说从后开始循环,那么最小的数就会从底向上冒出来,所以称之为冒泡;
代码:

function BubbleSort(arr){
    var flag = true;
    for(var i = 0;i<arr.length-1 && flag;i++){
        for(var j = arr.length-1;j >= i+1;j--){
            if(arr[j] < arr[j-1]){
                var temp = arr[j-1];
                arr[j-1] = arr[j];
                arr[j] = temp;
                flag  = true;
            }
        }
    }
    return arr;
}

分析:
1、每一次内循环都会把剩余的最小数往前推到已排序的下一个
2、经过n-1次大循环可以把最小数依次往前排列,最后一个数位置也肯定正确
3、如果有那一次内循环发现没有交换了,说明后面已经排好序,无需再排序了,提前结束

时间复杂度:
最糟糕的的是(n-1)+(n-2)+..+2+1 = n(n-1)/2;也就是O(n^2);最理想的是当数组本来就有序的时候,只用n-1次比较就好了;
稳定性:
由于冒泡的比较都是在相邻的元素之间比较,当两个元素相等时没有必要交换了,所以属于稳定的。

二、简单选择排序
基本思想:
通过n-i次关键字之间的比较,从n-i+1个记录中选取关键字最小的记录,并且和第i个记录交换。通俗来说既是每一次在剩余元素中找最小的记录,这里和冒泡有点像,但是在剩余元素中找最小的记录做法不一样,冒泡是最小的记录从底向上冒出来,但是选择排序是通过n-i次比较之后精确找出最小的记录是哪个。

function selcetSort(arr){
    var min;
    for(var i = 0;i<arr.length-1;i++){
        min = i;
        for(var j = i+1;j<arr.length;j++){
            if(arr[min] > arr[j]){
                min = j;
            }
        }
        if(i != min){
            var temp = arr[i];
            arr[i] = arr[min];
            arr[min] = temp;
        }
    }
    return arr;
}

分析:
1、每一次内循环都会把剩余最小元素的下标找到,如果跟i不同就交换
2、经过n-1次内循环之后最小数依次列,最后一个数位置也自动正确了。

时间复杂度:
其实最糟糕跟冒泡是一样的,比较数是n(n-1)/2,所以复杂度是O(n^2),但是交换次数是最少的,最多的时候也就是n-1次交换,冒泡的交换次数是比较多的,选择排序由于数据交换移动次数比较少,性能比较高,但是对于有一定顺序的数组来说还是用冒泡比较好。

稳定性:
直接看栗子:
5 8 5 2 9
第一次内循环的时候第一个5和2会交换,那么原来的两个相同元素5的顺序会改变。所以是不稳定的。

三、直接插入排序
基本思想:
将一个记录插入到一个已经排好序的有序表,从而得到一个新的、记录数增1的有序表。其实就是每次去找相应元素在前面有序序列的位置,从右到左与相应的元素比较,如果比对应元素要大就空出一个位置;

function insertSort(arr){
    for(var i=1;i<arr.length;i++){
        temp = arr[i];
        for(var j=i-1;arr[j] > temp;j--){
            arr[j+1] = arr[j];     // 比temp还大就自己往后退了
        }
        arr[j+1] = temp;   // 比a[j]还大的话就自己就只能在a[j+=1]位置了
    }
    return arr;
}

分析:
1、认定第一元素作为初始的有序序列,外循环n-1次就可以把后面的元素全部插入到左边的有序序列
2、每一次内循环都是把i位置的元素插入到左边的有序序列中,插入的方法是从i-1的位置开始键依次减小的元素跟第i个位置的数比较,比第i个元素大的元素往后靠直到找到比i小的为止(往后靠的办法就是将j的值赋值给j+1,那么第j个位置就空出来留给第i个位置或者下一个后退的元素)

时间复杂度:
平均比较和移动次数约为n^2/4因此时间复杂度为O(n^2),但是比冒泡和简单选择排序的性能要好一点

稳定性:
当有两个相同元素时,前面的元素先插入有序序列,当后面遇到一个相同元素时,该元素只能排在前面相同元素的后面,所以说插入排序是稳定的

点赞