快速排序

快速排序也是基于分治的思想,通过选择分割基准(分割基准可以取第一个元素,最后一个元素,中间元素,也可以随机的方式选取一个元素),将小于等于中间值的都放在左边,大于中间值的都放在右边,将数组分割为前后两个局部数组,然后对前后两个局部数组,通过递归调用进行分割,将数组分割为越来越小的子数组,在每一步的调用中,经过多次的交换,最终为中心元素找到最终位置,从而完成给定数组的排序。
可以看到快速排序的核心是分割,那么我们就先通过一个例子说明如何分割。
现在我们需要对数组 {3,9,8,1,5,6,2,5} 进行分割,数组的分割对象为 p 到 r (包含p和r), 这里选择分割的基准为 x(即A[r])。接下来对A中的元素进行移动,将小于等于 A[r] 的元素移动到 p 到 i 的范围(包含i), 将大于 A[r] 的元素移动到 i+1到 j (不包含 j )的范围内,最后将 A[i+1] 与 A[r] 交换。其中 i 初始化为 p-1, j 初始化为 p。

分割所用的下标.png

j 每经过依次循环就向后移动一个位置,从而将A[j]归入正确的组内,共有两种情况:
1)A[j] 大于 x 时不移动元素,直接将 j 向后移动一个位置,将 A[j] 归入“大于x的组”;
2)A[j] 小于等于 x,先让 i 向后移动一个位置,然后交换 A[i] 与 A[j],这样 A[j] 就进入了”小于等于 x 的组”,同时随着 j 向后移动一个位置,原本位于 A[i] 的元素又会回到“大于x的数组”。
最后将 A[i+1] 与 A[r] 交换,完成分割。
分割示例.jpg

接下来我们贴出代码:
<pre>
//分割
int partition(int A[], int n, int p, int r){
int i, j;
int t, x;
x = A[r];
i = p - 1;
for (j = p; j < r;j++){
if (A[j] <= x){
i++;
t = A[i]; A[i] = A[j]; A[j] = t;
}
}
t = A[i + 1]; A[i + 1] = A[r]; A[r] = t;
trace(A, n);
return i + 1;
};
//快速排序
void quickSort(int A[], int n, int p, int r){
int q;
if (p < r){
q = partition(A,n,p,r);
quickSort(A,n,p,q-1);
quickSort(A,n,q+1,r);
}
}
</pre>
结果:
下图是对数组进行快速排序的过程,便于和程序运行结果相对比。
快速排序步骤.jpg

运行结果.png

稳定性:快速排序在分割的过程中会交换不相邻的元素,因此属于不稳定的排序算法。
复杂度:如果快速排序在分割时能恰好选择中间值,则整个过程与归并排序一样大致分为 log2(n) 层,快速排序的平均复杂度为 O(nlogn)。
总结:快速排序与归并排序一样基于分治法,但其执行分割时就已经在原数组中完成了排序,因此不需要归并排序中的手动合并处理。此外归并排序需要O(n)的外部存储空间,快速排序则不需要额外的内存,是一种原地排序(内部排序)。在本例中我们选用的基准是 A[r], 因此在处理某些顺序的数据(例如一排序完毕的数据)时效率会大打折扣,最坏情况下复杂度甚至高达O(n2), 此外某些顺序的数据可能让递归深度过深,最终导致栈溢出,一般情况下,需要在基准的选择上多花些心思,比如随机选择,或者任选几个值后取中间值等。
至此,几种常见的排序方法都已经理解了,第一次静下心来理了理这几种算法,以上的理解大都源自下面这本书,讲得特别详细,对算法的讲解大部分有应用实例和框图解释,所以很容易理解,值得好好看一下!
挑战程序设计竞赛.png

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容

  • quicksort可以说是应用最广泛的排序算法之一,它的基本思想是分治法,选择一个pivot(中轴点),将小于pi...
    黎景阳阅读 441评论 0 1
  • 概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    蚁前阅读 5,164评论 0 52
  • 概述:排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    每天刷两次牙阅读 3,727评论 0 15
  • 1.插入排序—直接插入排序(Straight Insertion Sort) 基本思想: 将一个记录插入到已排序好...
    依依玖玥阅读 1,239评论 0 2
  • The danger of the single story Chimamanda Ngozi Adichie M...
    Zoe悦然阅读 4,019评论 0 3