排序算法

169 阅读2分钟

排序,就是让一组无序数据变成有序的过程。

1、衡量一个排序算法的优劣

  • 时间复杂度:具体包括,最好时间复杂度、最坏时间复杂度以及平均时间复杂度
  • 空间复杂度:如果空间复杂度为 1,也叫作原地排序
  • 稳定性:排序的稳定性是指相等的数据对象,在排序之后,顺序是否能保证不变

2、常见的排序算法及其思想

1、冒泡排序

  • 原理
    • 从第一个数据开始,依次比较相邻元素的大小
    • 如果前者大于后者,则进行交换操作
    • 通过多轮迭代,直到没有交换操作为止
  • 性能
    • 最好时间复杂度是 O(n):当输入数组刚好是顺序的时候,只需要挨个比较一遍就行了,不需要做交换操作,所以时间复杂度为 O(n)
    • 冒泡排序最坏时间复杂度会比较惨,是 O(nn)。也就是说当数组刚好是完全逆序的时候,每轮排序都需要挨个比较 n 次,并且重复 n 次,所以时间复杂度为 O(nn)
    • 很显然,当输入数组杂乱无章时,它的平均时间复杂度也是 O(n*n)
    • 冒泡排序不需要额外的空间,所以空间复杂度是 O(1)。冒泡排序过程中,当元素相同时不做交换,所以冒泡排序是稳定的排序算法
function bubble( arr ){
    let flage = true;
    for( let i=0; i<arr.length; i++){
        for( let j=0; j<arr.length - 1 -i; j++){
        
            //前一个值大于后一个值时,两个调换位置
            if( arr[j] > arr[j+1]){
                flage = false;
                [arr[j],arr[j+1]] = [arr[j+1],arr[j]]
            }
        }
        if( flage ) break;
    }
    return arr;
}
var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
bubble(arr) 

2、选择排序

  • 原理
    • 通过多轮迭代,依次找到当前位置应该对应的最小值
function selectSort( arr ){
    let len = arr.length;
    for( let i=0; i<len; i++ ){
    
        //找到当前位置i对应的最小值所位置所在的index
        let index = i;
        for( let j=i; j<len; j++ ){
            if( arr[index] > arr[j] ){
                index = j
            }
        }
        
        //交换位置
        [arr[i],arr[index]] = [arr[index],arr[i]]
    }
    
    return arr;
}
var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
selectSort(arr) 

3、插叙排序

  • 原理
    • 利用当前位置的值,依次对比前面的值
    • 当前面的值大于当前值时[j+1] = [j]
    • 最终让[j+1] = temp
function insertSort( arr ){
    let len = arr.length;
    for( let i=0; i<len; i++ ){
        let temp = arr[i];
        let j = i -1;
        
        //轮询替换前面比自己大的值
        while( j>= 0 && arr[j] > temp ){
            arr[j+1] = arr[j];
            j--;
        }
        arr[j+1] = temp
    }
    return arr;
}
var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
insertSort(arr) 

4、快速排序

function quickSort( arr, left ,right ){
    if( left < right ){
        let val = arr[right],
        i = left - 1;
        
        //当arr[j]小于等于val的值时,调换 arr[i], arr[j]的位置
        for( let j=left; j<=right; j++){
            if( arr[j] <= val ){
                i++;
                [ arr[i], arr[j]] = [arr[j],arr[i]]
            }
        }
        
        //递归调用
        quickSort(arr, left, i-1)
        quickSort(arr, i+1, right)
    }
    return arr;
}
var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
quickSort(arr,0,arr.length-1) 

5、分治排序