首页 > 编程语言 >算法学习--3 (快速排序)

算法学习--3 (快速排序)

时间:2024-10-08 18:19:15浏览次数:8  
标签:-- 复杂度 元素 算法 数组 排序 快速 基准

引言

快速排序(Quick Sort)是计算机科学中最流行的排序算法之一,它基于“分治”思想,通过递归地将数组分成两部分并分别排序,从而实现排序的目的。与冒泡排序和选择排序等简单算法相比,快速排序在平均情况下的性能非常优越,因此广泛应用于实际场景。

本文将详细介绍快速排序的工作原理、实现代码、时间复杂度分析及其优缺点。

快速排序的基本原理

快速排序的核心思想是:通过选取一个“基准”元素(pivot),将数组划分为两部分,一部分小于基准,另一部分大于基准。然后递归地对这两部分分别进行快速排序,最终达到整个数组有序。

快速排序的算法步骤
  1. 从数组中选择一个元素作为基准(通常选取第一个、最后一个、中间一个或随机一个元素)。
  2. 将数组分区:所有比基准小的元素放到基准的左边,所有比基准大的元素放到右边。
  3. 递归地对基准左右两部分进行快速排序。
  4. 重复步骤2和3,直到每个子数组都有序。

快速排序动画演示

快速排序的实现代码

下面是用C++实现的快速排序代码:

#include <iostream>
using namespace std;

// 分区函数,返回基准元素的正确位置
int partition(int arr[], int low, int high) {
    int pivot = arr[high];  // 选择最后一个元素作为基准
    int i = (low - 1);  // i指向小于基准的最后一个元素

    for (int j = low; j < high; j++) {
        if (arr[j] <= pivot) {
            i++;  // i向前移动
            swap(arr[i], arr[j]);  // 交换比基准小的元素
        }
    }
    swap(arr[i + 1], arr[high]);  // 将基准放到正确的位置
    return (i + 1);
}

// 快速排序主函数
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);  // 对基准右边排序
    }
}

// 打印数组
void printArray(int arr[], int size) {
    for (int i = 0; i < size; i++)
        cout << arr[i] << " ";
    cout << endl;
}

int main() {
    int arr[] = {10, 7, 8, 9, 1, 5};
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << "排序前的数组: ";
    printArray(arr, n);
    quickSort(arr, 0, n - 1);
    cout << "排序后的数组: ";
    printArray(arr, n);
    return 0;
}

时间复杂度分析

快速排序在大多数情况下表现非常高效。它通过递归地将数组分成两半,平均情况下每次都能将问题规模减半。因此,快速排序的平均时间复杂度为 O(n log n)。

  • 最坏情况:当每次划分的结果极为不平衡时,快速排序会退化为 O(n²) 的复杂度。最典型的例子是每次选择的基准都是数组的最大或最小值,这样每次递归只减少一个元素的规模。
  • 最好情况:在每次划分都能将数组等分时,快速排序的复杂度为 O(n log n),这是其平均情况的复杂度。
优化策略

为了避免快速排序在最坏情况下退化,可以采用以下优化策略:

  • 随机选取基准:通过随机选取基准元素,可以减少每次都选到最差基准的概率。
  • 三数取中:选取第一个、最后一个和中间元素的中位数作为基准,可以有效避免数组初始状态有序时的最坏情况。
快速排序的优缺点

优点

  • 平均时间复杂度低:快速排序的平均时间复杂度为 O(n log n),对于大多数实际问题表现非常高效。
  • 原地排序:快速排序的空间复杂度为 O(log n),因为它只需要一个额外的栈空间用于递归,不需要额外的数组来存储数据。
  • 应用广泛:快速排序广泛应用于许多编程语言的标准库中,如C++的 std::sort() 函数背后实现的就是快速排序。

缺点

  • 最坏时间复杂度高:在最坏情况下,时间复杂度会退化为 O(n²)。
  • 不稳定:快速排序不是稳定排序算法,即相同的元素在排序后相对位置可能发生变化。
适用场景

快速排序是一个通用的高效排序算法,适用于绝大多数情况下的数据排序。它在工程应用中非常普遍,尤其是在需要快速处理大量数据时。由于其原地排序的特性,快速排序在内存使用受限的情况下也具有优势。

总结

快速排序是一个高效的分治排序算法,它的平均时间复杂度为 O(n log n),在实际应用中具有广泛的应用场景。通过合理选择基准元素,可以避免最坏情况的发生。尽管它不是稳定排序,但它的效率和简单实现让它成为实际编程中首选的排序算法之一。

标签:--,复杂度,元素,算法,数组,排序,快速,基准
From: https://blog.csdn.net/2301_78323792/article/details/142765603

相关文章

  • 算法学习--4 (插入排序)
    引言插入排序(InsertionSort)是一种简单且直观的排序算法,常用于小规模数据的排序。它的工作原理与人类排序扑克牌的方式类似,每次将一个元素插入到已经排好序的部分,直到所有元素都插入完成。本文将介绍插入排序的原理、实现代码、时间复杂度分析以及优缺点。插入排序的基本原......
  • ansible中为什么不都是用shell模块写task,而是创建出一个一个的模块
    ansible的shell模块的功能非常强大,它甚至可以代替ansible的所有模块,比如像unarchive命令,在shell中可以分解为。通过scp命令传送包到远程,再通过tar命令对文件进行解压,再比如user模块可以直接在shell模块中调用useradd命令和usermod命令进行用户的管理,那么为什么还会有其他模......
  • 国际金价行情具体实现查询
    整体请求流程介绍:本次解析通过云市场的云服务来实现查询实时国际黄金的实时行情,首先需要准备选择一家可以提供查询的商品。步骤1:选择商品如图点击免费试用,即可免费申请该接口数据步骤2:调试输入对应的参数,找对对应的子接口,这里是伦敦金银点击《发起请求》,即可看......
  • 2020年华为杯数学建模竞赛A题代码和思路
    ASIC芯片上的载波恢复DSP算法设计与实现随着数字信号处理(DSP)技术的成熟以及芯片技术工艺的飞速发展,作为光传输领域中的关键技术之一,光数字信号处理在专用集成电路(ASIC)上的实现成为了研究重点。本文围绕着ASIC芯片中DSP算法设计流程中的主要步骤和常见问题,通过建立16QAM数......
  • 密码需包含数字、字母或符号至少两种以上字符组成且长度在6-20位的正则
    可以使用以下正则表达式来匹配密码需包含数字、字母或符号至少两种以上字符组成且6-20位的条件:varpattern=/^(?![0-9]+$)(?![a-zA-Z]+$)(?![^0-9a-zA-Z]+$).{6,20}$/;这个正则表达式使用了正向否定预查来确保密码包含至少两种字符类型(数字、字母或符号),并且长度在6到20......
  • 用AI构建小程序可行吗?
    随着移动互联网的快速发展,多端应用的需求日益增长。为了提高开发效率、降低成本并保证用户体验的一致性,前端跨端技术在如今的开发界使用已经非常普遍了,技术界较为常用的跨端技术有小程序技术、HTML5技术两大类。 2023年以来,伴随着AI技术在全球各行各业创造了生产力革命,而AI......
  • 20222325 2024-2025-1 《网络与系统攻防技术》实验一实验报告
    1.实验内容缓冲区溢出基本知识:堆栈、函数调用。shellcode技术以及其在各平台的运用与防御。BOF攻击防御技术。2.实验目标本次实践的对象是一个名为pwn1的linux可执行文件。该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。该程序同时包含另......
  • springcloud集成SkyWalking链路追踪技术
    在微服务多个服务调用过程中,随着服务数量增多,互相调用的变多,就会出现一些问题:1、调用链路,如何快速定位问题2、如果缕清微服务之间的依赖关系3、各个微服务接口性能分析4、整个业务流程的调用处理顺序 skywalking可以很好的处理这些问题,在springcloud微服务中如何整合skywal......
  • 10/8
    慧鱼机电实训理论与实践结合:通过实训,我们能够将课堂上学到的理论知识应用于实际操作中,加深对机电系统的理解。团队合作的重要性:在实训过程中,往往需要与同学们密切合作,分工合作不仅提高了效率,也培养了团队意识和沟通能力。解决问题的能力:在面对设备故障或调试难题时,我学会了冷......
  • GIS专业的就业前景
    地理信息系统(GIS)作为一门跨学科的领域,随着技术的发展和应用领域的拓宽,其就业前景日益广阔。GIS专业毕业生可以在多个行业中找到合适的职位,并且随着经验的积累,薪资和职业发展空间都相当可观。 1.就业方向GIS专业的毕业生就业方向多样,包括但不限于:......