C# 快速排序(QuickSort)

news2025/1/21 8:45:37

        QuickSort是一种基于分而治之算法的排序算法,它选择一个元素作为主元,并通过将主元放置在已排序数组中的正确位置,围绕所选主元对给定数组进行分区。

快速排序是如何工作的?
        QuickSort中的关键过程是partition()。分区的目标是将主元(可以选择任何元素作为主元)放置在已排序数组中的正确位置,并将所有较小的元素放在主元的左侧,将所有较大的元素放在主元的右侧。
        将枢轴放置在正确的位置后,在枢轴的每一侧递归地完成分区,最终对数组进行排序。

 

快速排序的工作原理

枢轴的选择:
选择枢轴有许多不同的选择。 
1、始终选择第一个元素作为枢轴。
2、始终选择最后一个元素作为基准(在下面实现)
3、选择一个随机元素作为基准。
4、选择中间作为枢轴。

分区算法:
        逻辑很简单,我们从最左边的元素开始,并跟踪较小(或等于)元素的索引i。遍历时,如果找到较小的元素,则将当前元素与 arr[i] 交换。否则,我们忽略当前元素。
        让我们借助以下示例来了解分区和快速排序算法的工作原理:
        考虑:arr[] = {10, 80, 30, 90, 40}。
        将10与枢轴比较,小于枢轴则依次排列。

QuickSort 中的分区:将主元与 10 进行比较 

        将 80 与枢轴进行比较。它大于枢轴。 

 

QuickSort 中的分区:将枢轴与 80 进行比较

        将 30 与枢轴进行比较。它小于枢轴,因此请相应地安排它。 

QuickSort 中的分区:将数据透视表与 30 进行比较

        将 90 与枢轴进行比较。它大于枢轴。 

 

QuickSort 中的分区:将枢轴与 90 进行比较 

        将枢轴布置在正确的位置。 

 

QuickSort 中的分区:将枢轴放置在正确的位置

快速排序的说明:
        由于分区过程是递归完成的,因此它不断地将主元放在排序数组中的实际位置。反复将枢轴放入其实际位置可以使数组排序。
        按照下图了解分区算法的递归实现如何帮助对数组进行排序。
主阵列上的初始分区:
 

快速排序:执行分区 

子数组的划分: 

 

快速排序:执行分区

快速排序的代码实现:

// C# implementation of QuickSort

using System;

class GFG {

    // A utility function to swap two elements
    static void swap(int[] arr, int i, int j)
    {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    // This function takes last element as pivot,
    // places the pivot element at its correct position
    // in sorted array, and places all smaller to left
    // of pivot and all greater elements to right of pivot
    static int partition(int[] arr, int low, int high)
    {
        // Choosing the pivot
        int pivot = arr[high];

        // Index of smaller element and indicates
        // the right position of pivot found so far
        int i = (low - 1);

        for (int j = low; j <= high - 1; j++) {

            // If current element is smaller than the pivot
            if (arr[j] < pivot) {

                // Increment index of smaller element
                i++;
                swap(arr, i, j);
            }
        }
        swap(arr, i + 1, high);
        return (i + 1);
    }

    // The main function that implements QuickSort
    // arr[] --> Array to be sorted,
    // low --> Starting index,
    // high --> Ending index
    static void quickSort(int[] arr, int low, int high)
    {
        if (low < high) {

            // pi is partitioning index, arr[p]
            // is now at right place
            int pi = partition(arr, low, high);

            // Separately sort elements before
            // and after partition index
            quickSort(arr, low, pi - 1);
            quickSort(arr, pi + 1, high);
        }
    }

    // Driver Code
    public static void Main()
    {
        int[] arr = { 10, 7, 8, 9, 1, 5 };
        int N = arr.Length;

        // Function call
        quickSort(arr, 0, N - 1);
        Console.WriteLine("Sorted array:");
        for (int i = 0; i < N; i++)
            Console.Write(arr[i] + " ");
    }
}

// This code is contributed by gfgking

输出
排序数组
1 5 7 8 9 10

快速排序的复杂度分析:
时间复杂度:
最佳情况:Ω (N log (N))
快速排序的最佳情况发生在每一步选择的主元将数组分成大致相等的两半时。
在这种情况下,算法将进行平衡分区,从而实现高效排序。
平均情况:θ ( N log (N))快速排序的平均情况性能在实践中通常非常好,使其成为最快的排序算法之一。
最坏情况:O(N2)快速排序的最坏情况发生在每一步的枢轴始终导致高度不平衡的分区时。当数组已经排序并且枢轴始终被选为最小或最大元素时。为了缓解最坏的情况,使用了各种技术,例如选择一个好的主元(例如,三的中位数)并使用随机算法(随机快速排序)在排序之前对元素进行混洗。
辅助空间:如果不考虑递归栈空间,O(1)。如果我们考虑递归堆栈空间,那么在最坏的情况下,快速排序的时间复杂度可能是 O ( N )。

快速排序的优点:
它是一种分而治之的算法,可以更轻松地解决问题。
它在大型数据集上非常有效。
它的开销很低,因为它只需要少量的内存即可运行。

快速排序的缺点:
它的最坏情况时间复杂度为 O(N 2 ),当主元选择不当时就会发生这种情况。
对于小数据集来说这不是一个好的选择。
它不是稳定的排序,这意味着如果两个元素具有相同的键,在快速排序的情况下,它们的相对顺序将不会保留在排序的输出中,因为这里我们根据枢轴的位置交换元素(不考虑它们的原始位置)职位)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1681894.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【动态规划】子序列问题II|最长定差子序列|最长的斐波那契数列的长度|最长等差数列|等差数列的划分

一、最长定差子序列 1218. 最长定差子序列 算法原理&#xff1a; &#x1f4a1;细节&#xff1a; 1.正常创建dp表&#xff0c;分析状态转移方程&#xff1a;可能b存在于多个不同的位置&#xff0c;那么要用哪个下标的dp呢&#xff1f; 用最后一个b的&#xff0c;因为用前面的可…

手机图片恢复不求人:手动找回丢失的照片!

无论是外出旅行、聚会还是日常点滴&#xff0c;我们总是习惯用手机记录下来&#xff0c;让美好的瞬间定格在一张张照片中。然而&#xff0c;有时因为误删、清空缓存或是更换手机&#xff0c;那些珍贵的照片突然消失了。手机图片恢复有什么简单易行、容易上手的方法吗&#xff1…

Flink 高可用之StandAlone-HA模式(一)

Flink 高可用之StandAlone-HA模式 压缩包: tar -xvzf flink-1.9.1-bin-scala_2.11.tgz -C /opt && cd /opt/flink-1.9.1 集群规划: 1.集群规划 - 服务器: node1(Master Slave): JobManager TaskManager- 服务器: node2(Master Slave): JobManager TaskManager- …

【介绍下JSON,JSON是什么?】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

【三十一】springboot+easyExcel实现多文件导出压缩包

互相交流入口地址 整体目录&#xff1a; 【一】springboot整合swagger 【二】springboot整合自定义swagger 【三】springboot整合token 【四】springboot整合mybatis-plus 【五】springboot整合mybatis-plus 【六】springboot整合redis 【七】springboot整合AOP实现日志操作 【…

用AI绘画制作虚拟网红!9个月涨粉30万!超强变现案例分享

大家好&#xff0c;我是向阳。 2023年是AI爆发的一年&#xff0c;AI的飞速发展&#xff0c;让创造AI虚拟人变得简单&#xff0c;于是有人发明一种玩法&#xff1a;AI虚拟网红&#xff0c;模拟真人的外观和生活方式&#xff0c;吸引流量和商家关注。 其中fit_aitana就是一个典型…

设备接入物联网平台必须掌握的关键信息——青创智通

工业物联网解决方案-工业IOT-青创智通 设备接入物联网平台需要掌握的信息相当丰富且复杂&#xff0c;这涉及到多个层面&#xff0c;包括技术细节、平台选择、安全性考虑以及后期管理与维护等。以下将详细阐述设备接入物联网平台所需掌握的关键信息。 首先&#xff0c;我们需要…

充电桩战火重燃,特来电、星星充电上演“龙虎斗”

配图来自Canva可画 小米Su7真的太火了&#xff0c;上市40天锁单量超过10万供不应求&#xff0c;给新能源汽车行业带来了新的活力&#xff0c;也促进了充电桩行业的发展。 据中国汽车工业协会数据&#xff0c;4月份新能源汽车产销分别完成87万辆和85万辆&#xff0c;同比分别增…

ROS 手眼标定 realsense435i+ur5e

手眼标定的原理 基坐标系&#xff08;base_tree&#xff09;和相机&#xff08;camera_tree&#xff09;两个坐标系属于不同的tree&#xff0c;通过将标签贴到手上&#xff0c;相机识别出标签的position和orention&#xff0c;并通过easy_handeye标定包得到tool0(机械手)&…

企业数据治理:挑战与机遇并存的道路

在数字化浪潮席卷全球的今天&#xff0c;数据已经成为企业最宝贵的资产之一。然而&#xff0c;如何有效地管理和利用这些数据&#xff0c;确保数据的准确性、可靠性和安全性&#xff0c;成为了摆在企业面前的一大难题。数据治理&#xff0c;作为这一难题的解决方案&#xff0c;…

03-行为型模式(共10种)

上一篇: 02-结构型设计模式(共7种) 1. Strategy(策略模式) 策略模式是一种行为型设计模式&#xff0c;它定义了一系列算法&#xff0c;将每个算法封装到独立的类中&#xff0c;并使它们可以互相替换。这样可以使算法的变化独立于使用算法的客户端。 在 C 中&#xff0c;策略模式…

数据结构复习指导之图的遍历

文章目录 图的遍历 考纲内容 复习提示 1.广度优先搜索 1.1BFS算法的性能分析 1.2BFS算法求解单源最短路径问题 1.3广度优先生成树 2.深度优先搜索 2.1DFS算法的性能分析 2.2深度优先的生成树和生成森林 3.图的遍历与图的连通性 4.知识回顾 图的遍历 考纲内容 &…

Signal 即将成为JavaScript的一部分

什么是响应性&#xff1f; 在过去的几年中&#xff0c;响应性成为了所有现代前端框架以及React库的核心。 对于不熟悉前端开发的人来说&#xff0c;起初这可能是一个令人困惑的概念&#xff0c;因为它改变了常规的、自上而下的、从调用者到被调用者的顺序工作流。 在响应性范…

GIT基础02 多机器协作等命令

前言 首先我们知道git给我们提供了分支管理的功能 我们一般使用master分支作为线上环境,master分支一般是一个稳定的分支 我们通常是会创建一个其他分支进行开发,这样不会影响线上的机器运行 如果没有git提供这样的分支功能,就无法做到这一套了 指令学习 假设软件出现问题咋办…

得物质量管理体系的建设与应用

一、背景 质量保障是一门基于软件测试的系统化工程&#xff0c;遵循渐进式的发展规律。通过因地制宜地制定落地策略&#xff0c;设计场景方案&#xff0c;获取试验结果&#xff0c;并加以循环往复。最终&#xff0c;在每一位得物测试工程师的共同努力下&#xff0c;积累出一套…

Moe 混合多专家模型 原理 + 大模型的有性繁殖

Moe 混合多专家模型 原理 大模型的有性繁殖 MoE 介绍标准 Transformer 编码器MoE Transformer 编码器专家网络层 大模型的有性繁殖mergekit 合并 多个专家模型 的方式1. SLERP&#xff08;球面线性插值&#xff09;2. TIES3. DARE4. Passthrough5. Linear mergekit 合并 多个专…

vue3中实现简繁体转换

由于项目在大陆和台湾同胞同步使用&#xff0c;因此需要实现中文的简繁体转换&#xff0c;实现输入简体&#xff0c;能搜索出简体和繁体的相关内容&#xff0c;输入繁体&#xff0c;也能搜索出简繁体相关内容。忽略简繁体&#xff0c;扩大搜索范围。 引入插件&#xff1a; np…

一休:一款专业的休息提醒软件

对于长期使用电子产品的人来说&#xff0c;保护眼睛至关重要&#xff0c;不论是工作还是学习&#xff0c;适当的休息都是必要的&#xff0c;保护视力要牢记20-20-20法则&#xff0c;眼科医生陶勇也科普过&#xff1a; 使用电脑工作和学习时&#xff0c;容易会忘记时间&#x…

在面对各种问题时,我们应该如何进行数据分析

python数据分析汇总 前言一、对比分析概念特征类型案例Matplotlib的颜色字母对照表解决遇到未知函数 二、相关性分析概念类型案例一案例二 三、时间序列分析概念类型案例 四、回归分析概念类型案例一案例二案例三 五、决策树概念计算过程案例 六、主成分分析概念计算过程案例 七…

【手势识别-UILongPressGestureRecognizer长按 Objective-C语言】

一、我们来说这个长按啊, 1.长按这个手势,也是,步骤都是一样的,首先,也是这三大步啊, 1)创建手势对象 2)对某一个view添加手势 3)实现手势的方法 首先,也是三大步, 1)创建手势对象:首先,你要告诉我,你要使用哪一个手势,我要使用一个叫做UILongPressGesture…