O(n^2)的排序算法

O(n^2)的排序算法

  • O(n^2)是比较基础的排序算法,效率较低,编码简答,易于实现,是一些简单情景的首选。
  • 在一些特殊的情况下,简单的排序算法更有效
  • 简单的排序算法思想衍生出复杂的排序算法
  • 作为子过程,改进更复杂的排序算法

选择排序 Selection Sort

需要将下列数从小到大排列

在这里插入图片描述

从第一个开始排,找到比第一个(8)后面最小的数,是1

在这里插入图片描述

然后将其交换位置

在这里插入图片描述

此时的1就是最终排序的位置

在这里插入图片描述

后面的依次类推

在这里插入图片描述
在这里插入图片描述

C++代码实现

#include <iostream>
#include <algorithm>

using namespace std;

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] );
    }

}

int main() {
	//硬生成序列
    int a[10] = {10,2,5,7,9,3,4,8,6,1};
    selectionSort(a,10);
    for( int i = 0 ; i < 10 ; i ++ )
        cout<<a[i]<<" ";
    cout<<endl;

    return 0;
}
稍加改造一下函数,使其对各种类型都通用
#include <iostream>
#include <string>

using namespace std;

template<typename T>
void selectionSort(T arr[], int n){

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

        int minIndex = i;
        for( int j = i + 1 ; j < n ; j ++ )
            if( arr[j] < arr[minIndex] )
                minIndex = j;

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

int main() {

    // 测试模板函数,传入整型数组
    int a[10] = {10,9,8,7,6,5,4,3,2,1};
    selectionSort( a , 10 );
    for( int i = 0 ; i < 10 ; i ++ )
        cout<<a[i]<<" ";
    cout<<endl;

    // 测试模板函数,传入浮点数数组
    float b[4] = {4.4,3.3,2.2,1.1};
    selectionSort(b,4);
    for( int i = 0 ; i < 4 ; i ++ )
        cout<<b[i]<<" ";
    cout<<endl;

    // 测试模板函数,传入字符串数组
    string c[4] = {"D","C","B","A"};
    selectionSort(c,4);
    for( int i = 0 ; i < 4 ; i ++ )
        cout<<c[i]<<" ";
    cout<<endl;
    return 0;
}

结果:1 2 3 4 5 6 7 8 9 10

1 2 3 4 5 6 7 8 9 10
1.1 2.2 3.3 4.4
A B C D

插入排序 Insert Sort

虽然作为O(n^2)的排序算法,但在数组近乎有序的情况下,它的排序效率及其的高,甚至比O(nlogn)的算法效率还要高,可以作为复杂算法中的子过程。

需要将下列数从小到大排列

在这里插入图片描述

先将第二个数(6)与前面的数相比较,小的话就交换位置

在这里插入图片描述

然后再看第三个数(2)跟前面的数相比较,2<8,所以交换位置,再继续跟前面的数(6)比较,2<6,所以继续交换位置

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

后面的依次类推

C++代码实现

template<typename T>
void insertionSort(T arr[], int n){

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

        // 寻找元素arr[i]合适的插入位置
        // 写法1
//        for( int j = i ; j > 0 ; j-- )
//            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需要经过三步,效率不是很高,以下是改进版的插入排序算法,不使用swap进行交换,而是通过先将数复制下来,再与前面的进行比对,总体思想是一样的。

先把第二个数(6)复制一份,先看看它适不适合放在当前位置,让6跟前面的数(8)作比较,因为6<8,所以显然不适合当前位置,而8适合当前位置。

在这里插入图片描述

把6往后移,因为是第一个元素了,所以直接把6放在这个位置

在这里插入图片描述
在这里插入图片描述

后面依次类推

C++代码实现

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

    for( int i = 1 ; i < n ; i ++ ) {
        // 写法3
        T e = arr[i];
        int j; // j保存元素e应该插入的位置
        for (j = i; j > 0 && arr[j-1] > e; j--)
            arr[j] = arr[j-1];
        arr[j] = e;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老陈聊架构

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值