快速排序是排序算法中效率比较高的一种,也是面试常被问到的问题。

快速排序(Quick Sort)是对冒泡排序的一种改进。它的基本思想是,通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。(数据结构,严蔚敏)。

更具体一点的说,首先我们从待排序列中选取一个元素作为支点(pivot),这个支点的选择可以任意选取,所以经常直接拿第一个元素作为支点,更好一点的办法是三者取中法,即取第一个元素,最后一个元素,中间一个元素,这三个值中间的中值(非最大最小)作为支点。支点选好之后,把支点放到待排序序列的第一个位置,如果你选的是第一个元素作为支点的话,不用做什么,如果是其他情况,那么就把选好的支点跟第一个元素交换一下。然后通过代码将所有比支点小的记录都放在它之前的位置,将所有比它大的记录都放到它的位置之后。由此最后可以以该支点的位置作分界线,将序列分割成两个子序列。这个过程我们称为一趟快速排序(或一次划分)。

一次快速排序的具体实现:

将支点放在序列的第一个位置,最左边。然后从高位下标high(初始值为最后一个元素的位置)开始往前搜索,找到第一个小于支点的元素,将其和支点元素交换,即把一个比支点小的元素放在了支点的位置,而支点现在所处的新位置之后的元素都是比其大的,因为这个位置是我们从高位找到第一个比支点小的元素的原先位置;然后从低位low(初始值为第一个元素的位置)开始往后搜索,找到第一个大于支点的记录,将其和支点元素交换,由于前面的交换中支点所处的位置之后的元素都比其大,通过这一次的交换的话,这个较大的元素现在所在的位置往后的元素都是大于支点的,而且,支点回到的新的位置之前的元素都是比支点小的。重复这两步,直到从低位搜索和从高位搜索的两个index(也可以理解为指针)相遇,即low ==  high。

其实,上面提到的每次交换元素的操作可以精简一下,对支点记录的赋值是多余的,因为只有在一趟排序结束时,才能确定支点的最后位置。所以有一个临时变量将支点的值记录下来就可以了。每次交换时,只把需要变换位置的元素放到新的位置就可以了。

下面是代码,这段代码采用第一个元素作为支点,如果没有用第一个元素作为支点的话,那么交换一下,把支点放到第一个位置即可,然后采用下面相同的代码:

        static int Partition(int[] numbers, int low, int high)
{
int pivot = numbers[low];
while (low < high)
{
while (low < high && numbers[high] >= pivot)
{
high--;
} numbers[low] = numbers[high]; while (low < high && numbers[low] <= pivot)
{
low++;
}
numbers[high] = numbers[low];
} numbers[low] = pivot;
return low;
}

上面是一次快速排序的代码,最后返回的是支点的位置。下面就是对支点左右两边的序列分别进行快速排序,当子序列只有两个元素时,再通过一次排序该子序列就是有序的了,由此实现整个序列有序。可见,这是一个递归的操作。只有当序列长度大于1时才进行快速排序,因为只有一个元素的序列肯定是有序的,所以跳出递归的条件是low<high。只有一个元素时,low 是等于 high的。

        static void QuickSort(int[] numbers, int low, int high)
{
if (low < high)
{
int partitionLocation = Partition(numbers, low, high);
QuickSort(numbers, low, partitionLocation - );
QuickSort(numbers, partitionLocation + , high);
}
}

调用的过程就如:

        static void Main(string[] args)
{
int[] numbers = { , , , , , , , };
QuickSort(numbers, , numbers.Length - );
}

就平均时间而言,快速排序是目前认为是最好的一种内部排序方法。(数据结构,严蔚敏)。

最后,快速排序的平均时间复杂度是O(nlogn),最坏情况是O(n2),如序列本身就有序时,将蜕变为冒泡排序。空间复杂度为O(logn),这是因为递归过程要维护一个栈。

如果不好理解的话,最好的办法就是对着代码,手动走几遍,或者找些有配图的书或文章看看。

小小c#算法题 - 6 - 快速排序 (QuickSort)的更多相关文章

  1. 小小c#算法题 - 11 - 二叉树的构造及先序遍历、中序遍历、后序遍历

    在上一篇文章 小小c#算法题 - 10 - 求树的深度中,用到了树的数据结构,树型结构是一类重要的非线性数据结构,树是以分支关系定义的层次结构,是n(n>=0)个结点的有限集.但在那篇文章中,只 ...

  2. 算法实例-C#-快速排序-QuickSort

    算法实例 ##排序算法Sort## ### 快速排序QuickSort ### bing搜索结果 http://www.bing.com/knows/search?q=%E5%BF%AB%E9%80% ...

  3. 排序算法四:快速排序(Quicksort)

    快速排序(Quicksort),因其排序之快而得名,虽然Ta的平均时间复杂度也是O(nlgn),但是从后续仿真结果看,TA要比归并排序和堆排序都要快. 快速排序也用到了分治思想. (一)算法实现 pr ...

  4. 小小c#算法题 - 7 - 堆排序 (Heap Sort)

    在讨论堆排序之前,我们先来讨论一下另外一种排序算法——插入排序.插入排序的逻辑相当简单,先遍历一遍数组找到最小值,然后将这个最小值跟第一个元素交换.然后遍历第一个元素之后的n-1个元素,得到这n-1个 ...

  5. 小小c#算法题 - 12 - Joseph Circle(约瑟夫环)

    约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数(从1开始报数),数到m的那个人出列:他的下一个人又从1开始报数,数到m的那个人又 ...

  6. 小小c#算法题 - 10 - 求树的深度

    树型结构是一类重要的非线性数据结构,树是以分支关系定义的层次结构,是n(n>=0)个结点的有限集.关于树的基本概念不再作过多陈述,相信大家都有了解,如有遗忘,可翻书或去其他网页浏览以温习. 树中 ...

  7. 小小c#算法题 - 9 - 基数排序 (Radix Sort)

    基数排序和前几篇博客中写到的排序方法完全不同.前面几种排序方法主要是通过关键字间的比较和移动记录这两种操作来实现排序的,而实现基数排序不需要进行记录项间的比较.而是把关键字按一定规则分布在不同的区域, ...

  8. 小小c#算法题 - 8 - 归并排序 (Merging Sort)

    “归并”的含义是将两个或两个以上的有序序列组合成一个新的有序序列.这个“归并”可以在O(n+m)的数量级上实现,但这同时也需要O(n+m)的空间复杂度.具体为:首先分配一个新的长度为n+m的空序列,然 ...

  9. 快速排序(quicksort)算法实现

    快速排序(quicksort)是分治法的典型例子,它的主要思想是将一个待排序的数组以数组的某一个元素X为轴,使这个轴的左侧元素都比X大,而右侧元素都比X小(从大到小排序).然后以这个X在变换后数组的位 ...

随机推荐

  1. 《机器学习实战》学习笔记第十二章 —— FP-growth算法

    主要内容: 一.  FP-growth算法简介 二.构建FP树 三.从一颗FP树中挖掘频繁项集 一.  FP-growth算法简介 1.上次提到可以用Apriori算法来提取频繁项集,但是Aprior ...

  2. lnmp 一键安装配置

    l系统需求: CentOS/RHEL/Fedora/Debian/Ubuntu/Raspbian/Deepin Server/Aliyun/Amazon/Mint Linux发行版 需要5GB以上硬盘 ...

  3. Linux- 自动备份MySQL数据库脚本

    数据安全很重要,所以日常中需要对数据库进行备份.

  4. R语言的学习笔记 (持续更新.....)

    1. DATE 处理 1.1 日期格式一个是as.Date(XXX) 和strptime(XXX),前者为Date格式,后者为POSIXlt格式 1.2 用法:as.Date(XXX,"%Y ...

  5. node.js 安装及配置(hello world)及 node 的包管理器(npm)

    下载地址:Download | Node.js,无脑下一步安装即可: 安装时,会自动将 node 可执行文件路径添加进 Path 内,这样进入 cmd 命令行,以查看 node 的安装版本: > ...

  6. bzoj1059ZJOI2017矩阵游戏

    小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏——矩阵游戏.矩阵游戏在一个N *N黑白方阵进行(如同国际象棋一般,只是颜色是随意的).每次可以对该矩阵进行两种操作:行交换操作:选 ...

  7. w3c上的SQL 教程---基本语法 语句学习

    SQL 教程路径:http://www.w3school.com.cn/sql/index.asp

  8. JS数组的sort排序

    数组sort方法排序var aa=[6,2,1,5]//默认是从小到大排序aa.sort()[1, 2, 5, 6] //下面也是从小到大排序aa.sort(function(a,b){return ...

  9. CF475D:CGCDSSQ

    浅谈\(RMQ\):https://www.cnblogs.com/AKMer/p/10128219.html 题目传送门:https://codeforces.com/problemset/prob ...

  10. Azure自动化部署服务 (1)

    Azure中已经发布了自动化部署服务的PaaS功能. 本文将介绍自动化服务Automation初始化过程. 在Azure Management Portal上左边可以看到Azure的各种服务,其中一项 ...