算法总结(4)快速排序
2016-04-02 18:05
323 查看
在算法的评判中,速度绝对是很重要的一点,而接下来要说的这个排序算法,既然敢命名为快速排序,就必然有它的过人之处。
一.算法思路
原始数组被分为两个子数组,第一个数组小于等于某选定值(枢轴),第二个数组大于等于某选定值。重复分割。直到全部为一元数组。
快速排序的本质是递归的,它应用于数组每层分割的两个数组中,应用了分而治之的思想。
选择一个好的枢轴是很重要的任务。
二.伪代码
quicklysort(a[])
if(a.length>1)
选择枢轴;
while a中还有元素
把element加入subarray1或者subarray2中;
quicksoft(subarray1);
quicksoft(subarray2);
三.代码实现
一.算法思路
原始数组被分为两个子数组,第一个数组小于等于某选定值(枢轴),第二个数组大于等于某选定值。重复分割。直到全部为一元数组。
快速排序的本质是递归的,它应用于数组每层分割的两个数组中,应用了分而治之的思想。
选择一个好的枢轴是很重要的任务。
二.伪代码
quicklysort(a[])
if(a.length>1)
选择枢轴;
while a中还有元素
把element加入subarray1或者subarray2中;
quicksoft(subarray1);
quicksoft(subarray2);
三.代码实现
/** * @author garypotter * @version 创建时间:2016年4月2日 下午6:21:19 * @TODO * 类说明 */ public class QuickSort { public static void main(String[] args) { //int[] a={5,2,3,8,1,9,10,13,4,11}; //int[] a={6,6,6,6,6,6,6,6,6,6}; int[] a={72,71,73,74,60,1,2,3,4,80}; int[] b={}; int[] c={1}; quicksort(a,0,a.length-1); quicksort(b, 0, b.length-1); quicksort(c,0,c.length-1); System.out.println(9/2); System.out.println("result:"+a[0]+" "+a[1]+" "+a[2]+" "+a[3]+" "+a[4]+" "+a[5]+" "+a[6]+" "+a[7]+" "+a[8]+" "+a[9]); } public static void quicksort(int[] a,int start,int end){ if(start>=end){ return; //如果只剩下一个,就返回!注意,一定要返回! } int pivotindex=findpivot(start,end);//选出一个枢轴 swap(a,pivotindex,end); //将枢轴放到尾部,注意,这里的尾部不仅仅是指a的尾部,而是分而划之的每一个小数组的尾部 int k=partition(a,start-1,end,end); //将当前数组分为两部分,返回的是右边数组的第一个元素在a中的下标; //注意,是start-1,左边的初始下标比左边的第一个数的下标小一,比如,第一次,0-1=-1; swap(a,k,end); //分了两部分之后把枢轴换到k这个位置 quicksort(a,start,k-1); //左右边同样,迭代 quicksort(a,k+1,end); // } public static int findpivot(int i,int j){ return (i+j)/2;//稍微优化一下,选择在中间的,尽量避免极端情况。 } public static void swap(int[] a,int m,int n){ int temp=a[m]; a[m]=a ; a =temp; } //重点,分为两部分,注意,此时最尾部的只用于比较,不会交换,分为两部分之后才交换 public static int partition(int[] a,int l,int r,int pivotindex){ do{ //基本思想是:找到左边的比枢轴大的,找到右边比枢轴小的,交换 while(a[++l]<a[pivotindex]); //最后一次,会找到右边这部分的最左边的数 //从-1开始,先增1,才是第一个元素,再判断是否大于尾部的;极端情况:所有输入相同,则一直比较到最后一个,等于,此时l等于length-1,进入下一步,在这个边界不会出错 while((l<r)&&a[pivotindex]<a[--r]);//&&自左向右运算,如果第一个表达式为false,则不再计算第二个表达式 //先--r,因为最右边的是枢轴,不用来比较,从右往左扫描,找出一个小于枢轴的。 swap(a,l,r);//最后l和r相遇,l=r,这时能跳出while }while(l<r); return l;//返回右边的第一个元素的下标 } }
相关文章推荐
- cannot restore segment prot after reloc: pemission denied
- Android开发实用技巧之三:定制自己的日志工具LogUtil.java
- [JSP] c:forEach 如何输出序号
- 在线支付子模块的设计与实现
- 49. Group Anagrams
- ColorFulButton2
- 对线性回归,logistic回归和一般回归的认识
- 绘图 画笔特效处理
- LCD驱动程序
- BZOJ1426
- SQLite分析之WAL机制
- 不知道说啥好
- Jade、EJS、JSHTML、Mustache、Handlebars 五大node模板引擎区别
- 学习很累 但是必须坚持
- 分类-1-逻辑回归(Logistic regression)、感知学习算法(perceptron learning algorithm)、牛顿迭代法
- Ubuntu安装docker
- Class.forName()详解
- Tarjan算法求强连通分量
- input text中不能显示空格后的内容
- oracl中为用户解锁