快速排序算法
Posted 2019wxw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快速排序算法相关的知识,希望对你有一定的参考价值。
分而治之D&C
分而治之不是一种解决问题的算法,而是一种希望问题分解,将复杂的问题划分为多个简单问题来解决的思想。
分而治之的思想重点:
(1)找出简单的基线条件
(2)确定如何缩小问题的规模,使其符合基线条件。
快速排序
例如快速排序问题,一个列表进行排序,如下图
首先选择列表中的一个元素作为基准元素,其他的元素都与这个元素做比较,找出小于这个基准值的值、大于基准值的值。这称为“分区”,这时有,
1)一个由所有小于基准值的数字组成的子数组;
2)基准值
3)一个由所有大于基准值的数组组成的子数组
然后再将“小于v”和“大于v”的数据块作为子数组,同样选择基准值,再进行上述类似操作,当执行到数据块中只有1个元素或者0个元素时,即完成排序。
这个问题中的基线条件是执行到数据块中只有1个或者0个元素;
例如下面的数组,进行排序:
根据选择的基准值,对这个数组进行分区的各种可能方式如下:
假设你将3用作基准值,可对得到的子数组进行快速排序。
还有一个例子,如下图:
算法复杂度
看一下其他的算法的复杂度(O表示法表示)
快速排序的性能高度依赖于你选择的基准值。
最糟情况:算法复杂度O(n^2)
假设总是将第一个元素用作基准值,且要处理的数组是有序的。由于快速排序算法不检查输入数组是否有序,因此它依然尝试对其进行排序。
注意,数组并没有被分成两半,相反,其中一个子数组始终为空,这导致调用栈非常长。
这个示例展示的是最糟情况,在最糟情况下,栈长为O(n),在调用栈的每层都涉及O(n)个元素,完成每层所需的时间都为O(n)。因此整个算法需要的时间为O(n) * O(n) = O(n^2)。
最佳情况:算法复杂度O(n log n)
假设总是将中间的元素用作基准值,在这种情况下,调用栈如下。
调用栈短得多!因为每次都将数组分成两半,所以不需要那么多递归调用。很快就到达了基线条件,因此调用栈短得多。
这个示例展示的是最佳情况,在最佳情况下,栈长为O(log n),每一层运行时间为O(n),所以整个算法需要的时间为O(n) * O(log n) = O(n log n)。
平均情况:算法复杂度O(n log n)
最佳情况也是平均情况。只要每次都随机地选择一个数组元素作为基准值,快速排序的平均运行时间就将为O(n log n)。快速排序是最快的排序算法之一,也是D&C典范。
如何选择基准值?
实现快速排序时,请随机地选择用作基准值的元素。快速排序的平均运行时间为O(n log n)。
总结
1)D&C将问题逐步分解。使用D&C处理列表时,基线条件很可能是空数组或只包含一个元
素的数组。
2)实现快速排序时,请随机地选择用作基准值的元素。快速排序的平均运行时间为O(n log n)。
3)大O表示法中的常量有时候事关重大,这就是快速排序比合并排序快的原因所在。
快速排序详解:http://c.biancheng.net/view/198.html
实例:
#include <stdio.h> int qusort(int s[],int start,int end) //自定义函数 qusort() { int i,j; //定义变量为基本整型 i=start; //将每组首个元素赋给i j = end; //将每组末尾元素赋给j s[0]=s[start]; //设置基准值 while(i<j) { while(i<j&&s[0]<s[j]) j--; //位置左移 if(i<j) { s[i]=s[j]; //将s[j]放到s[i]的位置上 i++; //位置右移 } while(i<j&&s[i]<=s[0]) i++; //位置左移 if(i<j) { s[j]=s[i]; //将大于基准值的s[j]放到s[i]位置 j--; //位置左移 } } s[i]=s[0]; //将基准值放入指定位置 if (start<i) qusort(s,start,j-1); //对分割出的部分递归调用qusort()函数 if (i<end) qusort(s,j+1,end); return 0; } int main() { int a[11], i; //定义数组及变量为基本整型 printf("请输入10个数:\\n"); for(i=1;i<=10;i++) scanf("%d",&a[i]); //从键盘中输入10个要进行排序的数 qusort(a,1,10); //调用qusort()函数进行排序 printf("排序后的顺序是:\\n"); for(i=1;i<=10;i++) printf("%5d",a[i]); //输出排好序的数组 printf("\\n"); return 0; }
运行结果:
以上是关于快速排序算法的主要内容,如果未能解决你的问题,请参考以下文章