排序算法大总结

这篇博客总结了多种排序算法,包括选择排序、插入排序(基础版与改进版)、冒泡排序和希尔排序,这些算法的时间复杂度均为O(n^2)。接着介绍了归并排序,它是O(nlogn)级别的算法,通过递归与合并操作实现排序。文章还讨论了不同排序算法在处理近乎有序数组时的效率差异,并提出了在特定情况下采用插入排序或改进版归并排序的优化策略。
摘要由CSDN通过智能技术生成

选择排序

思路:

从最左边的元素开始,逐个遍历,找到这一趟中的最小值,存到minIndex里面,最后这一趟结束,将它和这一趟开始遍历的位置i上的元素swap,直到最后一个位置上也就位。相当于选择出每一趟最小的元素,然后把它放到这一趟开始的地方。

基础版:
void selectionSort(int arr[], int n){

    for(int i = 0 ; i < n ; i ++){
        // 寻找[i, n)区间里的最小值
        int minIndex = i;
        for( int j = i + 1 ; j < n ; j ++ )
            if( arr[j] < arr[minIndex] )
                minIndex = j;

        swap( arr[i] , arr[minIndex] );
    }

}

插入排序

思路:

由于第一个元素可以默认为已排好序,因此可以从第二个元素开始遍历,每一趟使一个元素正确的插入到前面已排好序的数组中。如果这个元素比它前面的元素小,则swap一下,如果大于等于它前面的元素,说明它以及它前面的元素已经排好序了,这一趟结束。

插入排序和选择排序一个很大的区别就是插入排序每一趟有可能提前结束,即它只要到达一个位置大于等于它前面的元素,那么这一趟就已经排好了;而选择排序每一趟必须遍历完这一趟所有的元素,找到最小的那个,然后再把最小的那个和这一趟开始的元素进行swap,是不能提前结束的。

对于近乎有序的数组,适合用插入排序。
对于完全有序的数组,插入排序复杂度为 O(n) O ( n )

基础版:
void insertionSort(T arr[], int n){

    for( int i = 1 ; i < n ; i ++ ) {

        // 寻找元素arr[i]合适的插入位置
        // 写法1
        for( int j = i ; j > 0 ; j-- ) //注意这里j遍历到下标为1的位置就好了,因为下面是将位置j和位置j-1的元素进行比较
            if( arr[j] < arr[j-1] )
                swap( arr[j] , arr[j-1] );
            else
                break;

        // 写法2
       // for( int j = i ; j > 0 && arr[j] < arr[j-1] ; j -- )
       //     swap( arr[j] , arr[j-1] );

    }

    return;
}
改进版:

将原本一次次的swap操作,变成一次次比较,而在一趟的最后进行赋值。

插入排序算法针对完全排好序的数组是O(n)级别的算法,每次判断一下当前数就是正确位置,这一趟就退出了

改进后的插入排序避免了很多次unnecessary copy,由此非常适合基本排好序而不需要很多次变动的数组。

void insertionSort(T arr[], int n){

    for( int i = 1 ; i < n ; i ++ ) {
        // 写法3
        T e = arr[i];// 声明一个变量保存要插入的元素
        int j; // j保存元素e应该插入的位置
        f
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值