快速排序的原理

来源:互联网 发布:安心360定位软件 编辑:程序博客网 时间:2024/05/11 17:17

快速排序的原理

最近在面试的时候 被问了 快速排序的问题
Q: 这里有一组数据,想要找出最大的前n个数 ,应该怎么做
A: 这种题 当时的第一反应是 快速排序 因为冒泡排序的的时间复杂度是for循环嵌套 O(n^2) 而快速排序的时间复杂度是O(nlogn) ,当时问我为什么是O(nlogn)的时候 我蒙住了 。

先说快速排序的原理:

快速排序也是分治法思想的一种实现,他的思路是使数组中的每个元素与基准值(Pivot,通常是数组的首个值,A[0])比较,数组中比基准值小的放在基准值的左边,形成左部;大的放在右边,形成右部;接下来将左部和右部分别递归地执行上面的过程:选基准值,小的放在左边,大的放在右边。。。直到排序结束。

步骤:
1.找基准值,设Pivot = a[0]
2.分区(Partition):比基准值小的放左边,大的放右边,基准值(Pivot)放左部与右部的之间。
3.进行左部(a[0] - a[pivot-1])的递归,以及右部(a[pivot+1] - a[n-1])的递归,重复上述步骤。

需要的拓展知识:具有n个结点的完全二叉树的深度为 这里写图片描述
快速排序的原理
最近在面试的时候 被问了 快速排序的问题
Q: 这里有一组数据,想要找出最大的前n个数 ,应该怎么做
A: 这种题 当时的第一反应是 快速排序 因为冒泡排序的的时间复杂度是for循环嵌套 O(n^2) 而快速排序的时间复杂度是O(nlogn) ,当时问我为什么是O(nlogn)的时候 我蒙住了 。

先说快速排序的原理:

快速排序也是分治法思想的一种实现,他的思路是使数组中的每个元素与基准值(Pivot,通常是数组的首个值,A[0])比较,数组中比基准值小的放在基准值的左边,形成左部;大的放在右边,形成右部;接下来将左部和右部分别递归地执行上面的过程:选基准值,小的放在左边,大的放在右边。。。直到排序结束。

步骤:
1.找基准值,设Pivot = a[0]
2.分区(Partition):比基准值小的放左边,大的放右边,基准值(Pivot)放左部与右部的之间。
3.进行左部(a[0] - a[pivot-1])的递归,以及右部(a[pivot+1] - a[n-1])的递归,重复上述步骤。

需要的拓展知识:具有n个结点的完全二叉树的深度为

1、最优情况
在最优情况下,Partition每次都划分得很均匀,如果排序n个关键字,其递归树的深度就为 [log2n]+1( [x] 表示不大于 x 的最大整数),即仅需递归 log2n 次,需要时间为T(n)的话,第一次Partiation应该是需要对整个数组扫描一遍,做n次比较。然后,获得的枢轴将数组一分为二,那么各自还需要T(n/2)的时间(注意是最好情况,所以平分两半)。于是不断地划分下去,就有了下面的不等式推断:

这说明,在最优的情况下,快速排序算法的时间复杂度为O(nlogn)。
这里写图片描述
2、最糟糕情况
然后再来看最糟糕情况下的快排,当待排序的序列为正序或逆序排列时,且每次划分只得到一个比上一次划分少一个记录的子序列,注意另一个为空。如果递归树画出来,它就是一棵斜树。此时需要执行n‐1次递归调用,且第i次划分需要经过n‐i次关键字的比较才能找到第i个记录,也就是枢轴的位置,因此比较次数为 ,最终其时间复杂度为O(n^2)。

3、一般情况
最后来看一下一般情况,平均的情况,设枢轴的关键字应该在第k的位置(1≤k≤n),那么:这里写图片描述

原创粉丝点击