快速排序原理:
快速排序的三步走:
一,递推公式:
quick_sort(p,r)=partition(p,r)+quick_sort(p,q-1)+qucik_sort(q+1,r)
二,伪代码
quick_sort(A,p,r){
if p > = r then return
q = partition(A,p,r)
quick_sort(A,p,q-1)
quick_sort(A,q+1,r)
}
三,partition分区的原地排序实现
我们通过与基准值的比较,交换数组中的数字,这样就不需要我们一个个移动数字了。
- python版本
def quick_sort(s1,left,right):
if left >= right:
return
povit = partition(s1, left, right)
quick_sort(s1,left,povit - 1)
quick_sort(s1,povit + 1,right)
def partition(s1, left, right):
pivot = s1[right]
i = left
for j in range(left,right):
if s1[j] <pivot:
tmp = s1[i]
s1[i] = s1[j]
s1[j] = tmp
i += 1
tmp = s1[i]
s1[i] = s1[right]
s1[right] = tmp
return i
if __name__ == '__main__':
"""实现快排算法的难点在于如何设计partition这个分区"""
s1 = [1,2,31,23,34,45,314,3,45,43,415]
lens = len(s1)
quick_sort(s1,0,lens - 1)
print(s1)
- java 代码:
package Quick_Sort_Demo;
import edu.princeton.cs.algs4.StdRandom;
import java.util.Random;
/**快速排序的代码逻辑
*
*
1. @Author:Allen
2. @Date:5/17/2021 11:02 AM
*/
public class Quick_Demo3 {
private static void sort(Comparable[] a){
StdRandom.shuffle(a); // 调用api中方法,洗牌,避免原有顺序的干扰
sort(a,0,a.length-1); //准备排序,下标为0开始
}
private static void sort(Comparable[] a,int lo,int hi){//开始排序
if(lo>=hi) return; //如果说我们的下标最低位已经大于最高位,直接返回,排序结束
int z = partition(a,lo,hi);//分区操作,确定基准(pivot) z
sort(a,lo,z-1); //左边排序
sort(a,z+1,hi);//右边排序
}
//设置基准值
private static int partition(Comparable[] a,int lo,int hi){
int i=lo,j=hi+1; //
Comparable v=a[lo];
while (true){
while(less(a[++i],v)) if(i ==hi ) break; //左边lo开始加,右边hi+1开始减
while(less(v,a[--j])) if(j ==lo ) break;
if( i>= j) break;
exch(a,i,j);
}
exch(a,lo,j);
return j;
}
//实现数字之间的大小比较
private static boolean less(Comparable A,Comparable B){
return A.compareTo(B)<0;
}
//实现数字交换
private static void exch(Comparable[] a,int i,int j){
Comparable temp = a[i];
a[i]=a[j];
a[j]=temp;
}
public static void main(String[] args) {
//我们设置1000个数值
Integer arr[] = new Integer[1000];
for(int i=0;i<1000;i++){
arr[i]=new Random().nextInt(1000)+1;
}
//计算运行的时间
long start = System.currentTimeMillis();
sort(arr);
long end = System.currentTimeMillis();
System.out.println("使用时间"+(end-start));
for (int i:
arr) {
System.out.print(i+" ");
}
}
}
-
总结:快速排序,1962年由东尼·霍尔提出。作为对冒泡排序的改进,其性能不稳定,但是平均性能佳。他的时间复杂度为O(nlogn)。
我们在真实的开发环境中以快排为主,不适用归并排序的原因在于其空间复杂度更高,而快排可支持原地排序。