八大排序算法【上】

冒泡排序

冒泡排序是一种 稳定 的排序算法。

它的工作原理是每次检查相邻两个元素,如果前面的元素与后面的元素满足给定的排序条件,就将相邻两个元素交换。当没有相邻的元素需要交换时,排序就完成了。

假设我们想要从小到大进行排序:

  • 第一次冒泡:将最大值放到了数组的最后一位;

  • 第二次冒泡:将第二大值放在数组的倒数第二位;

  • 以此类推。

cpp 复制代码
void BubbleSort(int arr[], int num)
{
    // 需要 num-1 次冒泡
    for (int i = 0; i < num - 1; ++i)
    {
        for (int j = 0; j < num - i - 1; ++j)
        {
            if (arr[j] > arr[j + 1]) swap(arr[j], arr[j + 1]);
        }
    }
}

复杂度分析:

当序列完全有序时,冒泡排序只需遍历一遍数组,不用执行任何交换操作,时间复杂度为 O(N);

在最坏情况下,冒泡排序要执行 ( n − 1 ) ⋅ n / 2 (n-1)·n/2 (n−1)⋅n/2次交换操作,时间复杂度为 O ( N 2 ) O(N^{2}) O(N2);

冒泡排序的平均时间复杂度为 O ( N 2 ) O(N^{2}) O(N2)。

选择排序

每次选择一个最大/最小的数,与当前位置的数进行交换。

由于 swap(交换两个元素)操作的存在,可能打乱相等数的相对顺序 ,因此选择排序是一种 不稳定 的排序算法。

cpp 复制代码
void SelectionSort(int arr[], int num)
{
    // 需要 num-1 次选择
    for (int i = 0; i < num - 1; ++i)
    {
        int mini = i;
        for (int j = i; j < num; ++j)
        {
            if (arr[j] < arr[mini]) mini = j;
        }
        swap(arr[i], arr[mini]);
    }
}

复杂度分析:

最优时间复杂度、平均时间复杂度和最坏时间复杂度均为 O ( N 2 ) O(N^{2}) O(N2)。

插入排序

插入排序是一种 稳定 的排序算法。

插入排序的思想:将当前元素与已经排好序的子数组中的元素逐个比较,找到合适的位置插入当前元素。

cpp 复制代码
void InsertionSort(int arr[], int num)
{
    // 从下标 1 开始
    for (int i = 1; i < num; ++i)
    {
        int cur = arr[i];
        int index = i;

        // 将大于 cur 的元素向右移动
        while (index - 1 >= 0 && arr[index - 1] > cur)
        {
            arr[index] = arr[index - 1];
            index--;
        }

        // 将 cur 插入到正确的位置
        arr[index] = cur;
    }
}

复杂度分析:

最优时间复杂度为 O(N),最坏时间复杂度和平均时间复杂度都为 O ( N 2 ) O(N^{2}) O(N2)。

希尔排序(**)

希尔排序是一种改进版的插入排序,其基本思路如下:

  • 选择增量: 选择一个增量,来决定元素之间的间隔,通常增量选择数组总长度的一半

  • 分组排序: 根据选定的增量,将数组元素分成若干组;对于每一组,使用插入排序的方法进行排序;

  • 逐步缩小增量: 逐步减小增量并重复上述分组和排序步骤,直至增量为 1。

当增量减小至 1 时,相当于进行一次普通的插入排序,此时数组已经被排好序了。

因为希尔排序进行了分组,可能打乱相等数的相对位置 ,希尔排序是一种 不稳定 的排序算法。

cpp 复制代码
void ShellSort(int arr[], int num)
{
    // 选择增量
    int dist = num / 2;
    while (dist)
    {
        for (int i = dist; i < num; ++i)
        {
            int cur = arr[i];
            int index = i;
            while (index - dist >= 0 && arr[index - dist] > cur)
            {
                arr[index] = arr[index - dist];
                index -= dist;
            }
            arr[index] = cur;
        }
        dist /= 2;  
    }     
}

复杂度分析:

通常情况下,希尔排序的时间复杂度介于 O ( n log ⁡ 2 n ) O(n \log^2 n) O(nlog2n) 和 O ( n 2 ) O(n^2) O(n2) 之间。

相关推荐
郝学胜-神的一滴14 分钟前
Qt 高级编程 040:按钮悬浮弹出滑块弹窗的完整攻略
开发语言·c++·qt·软件工程·用户界面
Tongzhi202631 分钟前
从部署到运维:通芝科技无感考勤一体机的全流程效率解析
运维·数据结构·科技·算法·贪心算法
Wang's Blog1 小时前
AI Agent白手起家30: 动态示例选择器之根据长度选择 Few Shot 示例
算法
oyguyteggytrrwwwrt2 小时前
自制交叉线路识别算法
算法
手写码匠2 小时前
华为云Flexus+DeepSeek征文|Dify 多智能体协同编排实战:R1 规划 + V3 执行,构建企业 Agent 团队
人工智能·深度学习·算法·aigc
晓天衡宇•评测社区3 小时前
FSR-Bench 前沿科学推理榜单发布:GPT-5.5 居首,“会推理”未必“能答对”
算法
程序喵大人5 小时前
【C++进阶】STL算法与函数对象 - 02 sort为什么需要随机访问迭代器
开发语言·c++·算法
hanlin035 小时前
动态规划专练:力扣第121、122题
笔记·算法·leetcode
To_OC5 小时前
LC 74 搜索二维矩阵:换皮的二分查找,我居然一开始没看出来
javascript·算法·leetcode
文心快码BaiduComate5 小时前
文心快码荣获“中国优秀软件产品”,实力再获国家级认可
算法·代码规范