当前位置: 首页 > article >正文

C语言:排序

1. 插入排序 (Insertion Sort)

插入排序是一种简单直观的排序算法,它的工作原理类似于整理扑克牌。它的基本思想是将数组分为已排序部分和未排序部分,每次从未排序部分取出一个元素,插入到已排序部分的合适位置。

步骤
  1. 从数组的第二个元素开始(假设第一个元素是已排序部分)。
  2. 将当前元素与已排序部分的元素从后向前比较,找到合适的位置插入。
  3. 重复上述过程,直到所有元素都被插入到合适的位置。
示例代码(C语言):
void insertionSort(int arr[], int n) {
    for (int i = 1; i < n; i++) {
        int key = arr[i];
        int j = i - 1;
        while (j >= 0 && arr[j] > key) {
            arr[j + 1] = arr[j];
            j--;
        }
        arr[j + 1] = key;
    }
}
性能分析
  • 时间复杂度
    • 最好情况:O(n)(数组已经有序)。
    • 最坏情况:O(n^2)(数组逆序)。
    • 平均情况:O(n^2)
  • 空间复杂度O(1)(原地排序)。
  • 稳定性:稳定(不改变相同元素的相对顺序)。
适用场景
  • 适用于小规模数据或部分有序的数据。

2. 选择排序 (Selection Sort)

选择排序是一种简单直观的排序算法,它的工作原理是每次从未排序部分选择最小(或最大)的元素,放到已排序部分的末尾。

步骤
  1. 将数组分为已排序部分和未排序部分。
  2. 从未排序部分中找到最小元素,与未排序部分的第一个元素交换位置。
  3. 重复上述过程,直到所有元素都被排序。
示例代码(C语言):
void selectionSort(int arr[], int n) {
    for (int i = 0; i < n - 1; i++) {
        int minIndex = i;
        for (int j = i + 1; j < n; j++) {
            if (arr[j] < arr[minIndex]) {
                minIndex = j;
            }
        }
        // 交换最小元素到已排序部分的末尾
        int temp = arr[i];
        arr[i] = arr[minIndex];
        arr[minIndex] = temp;
    }
}
性能分析
  • 时间复杂度
    • 最好、最坏、平均情况:O(n^2)
  • 空间复杂度O(1)(原地排序)。
  • 稳定性:不稳定(交换操作可能改变相同元素的相对顺序)。
适用场景
  • 适用于小规模数据,尤其是内存受限的场景。

3. 快速排序 (Quick Sort)

快速排序是一种高效的排序算法,基于“分治法”的思想。它通过选择一个“基准元素”(pivot)将数组分为两部分:小于基准的部分和大于基准的部分,然后递归地对两部分进行排序。

步骤
  1. 选择一个基准元素(通常是数组的第一个或最后一个元素)。
  2. 将数组分为两部分:一部分小于基准,另一部分大于基准。
  3. 递归地对两部分进行快速排序。
示例代码(C语言):
void quickSort(int arr[], int low, int high) {
    if (low < high) {
        int pi = partition(arr, low, high); // 分区
        quickSort(arr, low, pi - 1); // 递归排序左半部分
        quickSort(arr, pi + 1, high); // 递归排序右半部分
    }
}

int partition(int arr[], int low, int high) {
    int pivot = arr[high]; // 选择最后一个元素作为基准
    int i = low - 1;
    for (int j = low; j < high; j++) {
        if (arr[j] < pivot) {
            i++;
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    }
    // 将基准元素放到正确位置
    int temp = arr[i + 1];
    arr[i + 1] = arr[high];
    arr[high] = temp;
    return i + 1;
}
性能分析
  • 时间复杂度
    • 最好情况:O(n log n)(每次分区均匀)。
    • 最坏情况:O(n^2)(每次分区极不均匀,例如数组已经有序)。
    • 平均情况:O(n log n)
  • 空间复杂度O(log n)(递归栈的深度)。
  • 稳定性:不稳定(分区操作可能改变相同元素的相对顺序)。
适用场景
  • 适用于大规模数据的排序,尤其是随机数据的排序。

4. 冒泡排序 (Bubble Sort)

冒泡排序是一种简单的排序算法,它的工作原理是通过重复地遍历数组,依次比较相邻元素并交换顺序错误的元素。每一轮遍历都会将未排序部分的最大元素“冒泡”到末尾。

步骤
  1. 从数组的第一个元素开始,依次比较相邻元素。
  2. 如果前一个元素大于后一个元素,交换它们。
  3. 重复上述过程,直到没有需要交换的元素。
示例代码(C语言):
void bubbleSort(int arr[], int n) {
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}
性能分析
  • 时间复杂度
    • 最好情况:O(n)(数组已经有序)。
    • 最坏情况:O(n^2)
    • 平均情况:O(n^2)
  • 空间复杂度O(1)(原地排序)。
  • 稳定性:稳定(不改变相同元素的相对顺序)。
适用场景
  • 适用于小规模数据,尤其是教学和理解排序算法的场景。

对比总结

算法时间复杂度空间复杂度稳定性特点
插入排序O(n^2)O(1)稳定适合小规模数据或部分有序数据
选择排序O(n^2)O(1)不稳定简单直观,适用于小规模数据
快速排序O(n log n)O(log n)不稳定高效,适用于大规模数据
冒泡排序O(n^2)O(1)稳定简单易于理解

http://www.kler.cn/a/443348.html

相关文章:

  • [Git] git cherry-pick
  • C语言的语法
  • arcgisPro加载CGCS2000天地图后,如何转成米单位
  • SpringCloud系列教程:微服务的未来(十)服务调用、注册中心原理、Nacos注册中心
  • SpringBoot | 使用Apache POI库读取Excel文件介绍
  • ChatGPT网络错误如何解决
  • uniapp v-tabs修改了几项功能,根据自己需求自己改
  • Java原生实现代码沙箱的实现
  • 中阳科技:从量化交易到智能金融的创新实践
  • go 中使用redis 基础用法
  • 工具篇-postman快速导入全局变量设置简单压测
  • 如何在window 使用 conda 环境下载大模型
  • VUE+Node.js+mysq实现响应式个人博客|项目初始化+路由配置+基础组件搭建
  • Pikachu-XXE靶场(注入攻击)
  • Hibernate、JPA、Spring DATA JPA、Hibernate 代理和架构
  • Jest 入门指南:从零开始编写 JavaScript 单元测试
  • 源码分析之Openlayers中MousePosition鼠标位置控件
  • Redis Sentinel(哨兵) 和 Redis Cluster(集群)
  • 单元测试-Unittest框架实践
  • android RadioButton + ViewPager+fragment
  • 【Web】PolarCTF2024秋季个人挑战赛wp
  • KMP算法基础
  • 【Lua热更新】下篇 -- 更新中
  • Webpack常见的Plugin有哪些?
  • Java 初学者的第一个 SpringBoot3.4.0 登录系统
  • 【安当产品应用案例100集】032-重塑企业SaaS平台的PostgreSQL凭据管理体系