排序算法总结(6)--快速排序
来源:互联网 发布:java web进销存源码 编辑:程序博客网 时间:2024/05/28 15:20
一、简介
快速排序是冒泡排序的改进。可以看成是一个分治的过程。首先将数组A[p,…r]分成三部分:A[p,…,q-1],A[q],A[q+1,…,r],A[p,…,q-1]中的每一个元素都比A[q]小,而A[q+1,…,r]的每一个元素都比A[q]大。然后分别对A[p,…,q-1]和A[q+1,…,r]递归调用快速排序。当左右两部分排序好之后,即完成了整个数组的排序。
那么如何计算下标q是整个快速排序的关键。首先选择一个元素作为主元,围绕它来划分A[p,…r],这个主元也是最后的A[q]。划分过程中需要两个指针,一个j用来遍历数组,另一个i指向被交换的索引。从数组的左端开始遍历,如果A[j]小于主元,i++,并且A[i]和A[j]交换,如果大于等于主元,则不交换,当数组遍历完毕之后,将主元和A[i+1]交换。
快速排序是冒泡排序的改进。在冒泡排序中,每次循环改变一个元素的位置,并确定这个元素的位置,即将这个元素“浮”到最前面的位置。在快速排序中,每次改变多个元素的位置,并确定一个元素的位置,将这个元素“浮”到合适的位置。快速排序在每次循环中,交换的次数明显减少。
二、伪代码
2.1 递归
quickSort(A,p,r) if p<r q=partition(A,p,r) quickSort(A,p,q-1) quickSort(A,p+1,r)partition(A,p,r) x=A[r] i=p-1 for j=p tp r-1 if A[j]<x i++ swap(A[i],A[j]) swap(A[i+1],A[r]) return i+1
2.2 非递归
使用一个栈辅助,存储p,q,r
loopQuickSort(A) S=null //创建一个栈 start=0; end=A.length-1 S.push(start) S.push(end) while(!S.isEmpty) end=S.pop() start=S.pop() q=partition(A,start,end) if(start<q-1) S.push(start) S.push(q-1) if(end>q+1) S.push(q+1) S.push(end)
三、代码实现
3.1 递归
public static void quickSort(int[] array,int p,int r){ //p95 if(p<r){ int q=partition(array,p,r); quickSort(array,p,q-1); quickSort(array,q+1,r); } }public static int partition(int[] array,int p,int r){ //p95 int x=array[r]; int i=p-1; for(int j=p;j<r;j++){ if(array[j]<=x){ i+=1; int temp=array[i]; array[i]=array[j]; array[j]=temp; } } i+=1; array[r]=array[i]; array[i]=x; return i; }
时间复杂度 O(nlgn)
空间复杂度 原址排序,递归调用需要辅助空间
3.2 非递归
public static void loopQuickSort(int[] array){ //p95 Stack<Integer> s=new Stack<Integer>(); int start=0; int end=array.length-1; s.push(start); s.push(end); while(!s.isEmpty()){ end=s.pop(); start=s.pop(); int q=partition(array,start,end); if(start<q-1){ s.push(start); s.push(q-1); } if(end>q+1){ s.push(q+1); s.push(end); } } }public static int partition(int[] array,int p,int r){ //p95 int x=array[r]; int i=p-1; for(int j=p;j<r;j++){ if(array[j]<=x){ i+=1; int temp=array[i]; array[i]=array[j]; array[j]=temp; } } i+=1; array[r]=array[i]; array[i]=x; return i; }
时间复杂度O(nlgn)
空间复杂度:需要一个栈辅助
四、注意事项
1、快速排序每一次循环可以至少确定一个元素的位置
2、快速排序的非递归不一定比递归快
3、当需要排序的序列中有大量的相等的元素时,用快速排序性能尚可,但还有很大的改进空间,可以设计算法,将序列分成三部分,第一部分和第三部分和之前一样,第二部分存放和主元相同的元素,之后的比较只用在第一和第三部分进行。
- 排序算法总结(6)--快速排序
- 排序算法总结----快速排序
- 快速排序算法总结
- 快速排序算法总结
- 【算法总结】快速排序算法
- 排序算法总结之快速排序、归并排序、shell排序
- 排序算法总结(6)——快速排序
- 常用排序算法总结6一一快速排序
- 【排序算法】快速排序超级总结
- 排序算法总结(五)快速排序
- 排序算法总结之快速排序
- 排序算法总结(快速排序)
- iOS算法总结-快速排序
- 【朝花夕拾之排序算法总结】 快速排序,堆排序总结
- 算法导论-插入排序,归并排序,快速排序总结
- 常用排序算法总结(二) ---- 插入排序,快速排序
- C++ 排序算法总结 堆排序 快速排序
- 排序算法总结---交换排序之快速排序
- 胡兆进个人简历
- 前台与servlet交互乱码问题
- 埃氏筛法中的lambda表达式
- J
- 用Python一键搭建Http服务器
- 排序算法总结(6)--快速排序
- iOS开发网络篇
- 特长生模拟——采药
- 偏偏在面试的时候踏入一个大坑--360浏览器兼容模式
- stdcall 函数调用过程(以delphi为例),还有负数的补码
- 第5章 表单控件绑定
- 最佳课题选择(Vijos-1198)
- 【实验六】JPEG原理分析及JPEG解码器的调试
- 每天一个 Linux 命令(34):du 命令