常见排序——上篇(冒泡、插入、排序)

常见排序——上篇

在这里插入图片描述

  • 针对排序算法的空间复杂度,引入了新的概念——原地排序,指的空间复杂度为O1的排序算法。
  • 稳定性也是排序算法的一个指标,如果排序的序列中存在相同的元素,经过排序之后,相等元素之间原有的先后顺序不变。不变的排序算法叫作稳定的排序算法;如果前后顺序发生变化,那对应的排序算法就叫作不稳定的排序算法
    稳定算法排序用途:例如电商中一个对象包括两个数据,金额和下单时间,如果要求最终排序结果是金额从低到高,金额相同的按照下单时间先后排序;这类问题就可以用到稳定排序算法,先通过下单时间进行排序,然后再通过金额进行稳定排序,金额相同的会按照前面时间排序的顺序不变。
    [图片]

冒泡排序(Bubble Sort)

冒泡排序就会操作相邻的两个数据,一次冒泡会让至少一个元素移动到它应该在的位置,重复 n 次,就完成了 n 个数据的排序工作。

#include <iostream>
#include <cstring>
//自己写的还可以改进
using namespace std;
const int N = 1010;
int n;
int a[N];

int main() {
    cin >> n;
    memset(a, -1e9, sizeof a);
    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
    }
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= n; ++j) {
            if (a[j] < a[j - 1]) swap(a[j], a[j - 1]);
        }
    }

    for (int i = 1; i <= n; ++i) {
        cout << a[i] << endl;
    }
    return 0;
}
  • 只需要常量级空间所以是O(1),是原地排序算法
  • 稳定排序
  • 时间复杂度O(n^2)

有序度”和“逆序度”

有序元素对:a[i] <= a[j], 如果 i < j
[图片]

逆序元素对:a[i] > a[j], 如果 i < j
逆序度 = 满有序度 - 有序度

插入排序(Insertion Sort)

[图片]

  • 如何实现:
    首先,我们将数组中的数据分为两个区间,已排序区间和未排序区间。初始已排序区间只有一个元素,就是数组的第一个元素。插入算法的核心思想是取未排序区间中的元素,在已排序区间中找到合适的插入位置将其插入,并保证已排序区间数据一直有序。重复这个过程,直到未排序区间中元素为空,算法结束。
    插入排序也包含两种操作,一种是元素的比较,一种是元素的移动。
#include <iostream>

using namespace std;
const int N = 1010;
int a[N];
int n;

int main() {
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
    }

    for (int i = 2; i <= n; ++i) {
        int temp = a[i];
        int j = i - 1;
        for (; j >= 1; --j) {
            if (a[j] > temp) a[j + 1] = a[j];
            else break;
        }
        a[j + 1] = temp;
    }

    for (int i = 1; i <= n; ++i) {
        cout << a[i] << endl;
    }
    return 0;
}
  • 空间复杂度是 O(1),也就是说,这是一个原地排序算法
  • 插入排序是稳定的排序算法
  • 平均时间复杂度为 O(n^2)

选择排序(Selection Sort)

分已排序区间和未排序区间。但是选择排序每次会从未排序区间中找到最小的元素,将其放到已排序区间的末尾。
**[图片]

#include <iostream>

using namespace std;
const int N = 1010;
int n;
int a[N];

int main() {
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
    }


    for (int i = 1; i <= n; ++i) {
        int mini = 1e9;
        for (int j = i; j <= n; ++j) {
            if (mini >= a[j]) {
                mini = a[j];
                swap(a[i], a[j]);
            }
        }
    }

    for (int i = 1; i <= n; ++i) {
        cout << a[i] << endl;
    }
    return 0;
}
  • 选择排序空间复杂度为 O(1),是一种原地排序算法
  • 选择排序是一种不稳定的排序算法
  • 平均情况时间复杂度都为 O(n^2)
    [图片]
    注释:本文主要参考了 11 | 排序(上):为什么插入排序比冒泡排序更受欢迎?
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值