目录
1.排序原理
1.首先设定一个分界值,通过该分界值将数组分为左右两部分。
2.将大于或等于分界值的数据放到数组右边,小于分界值的放到数组的左边。此时左边部分中各元素小于或等于分界值,而右边部分中各元素都大于或等于分界值。
3.然后,左边和右边的数据就可以独立排序,对于左侧的数据元素,又可以去一个分界值,将数组分为两个部分,在左边置较小值,右边置较大值。右侧数据也可以做类似处理。
4.重复上述过程,可以看出这是一个递归操作,通过递归将左侧部分排序好,再递归排序好右侧数据,当左侧和右侧的数据排完序后,整个数组的排序就完成了
2.快速排序的API设计
类名 | Quick |
构造方法 | Quick():创建Quick对象 |
成员方法 | 1.public static void sort(Comparable[ ] a):数组内进行排序 2.private static void sort(Comparable[ ] a,int l,int h):对数组a中索引l到h之间的元素进行排序 3.public static int partition(Comparable[ ] a,int l,int h):对数组中,从索引l到h之间的元素进行分组,并返回分组界限对应的索引 4.private static boolean less(Comparable v,Comparable w): 判断v是否小于w 5.private static void exch(Comparable[ ] a,int i,int j):交换a数组中,索引i和索引j处的值 |
3.切分原理
1.找一个基准值,用两个指针分别指向数组的头部和尾部。
2.先从尾部向头部找一个比基准值小的元素,搜索到就停止,并记录指针位置。
3.再从头部向尾部搜索一个比基准值大的元素,搜索到就停止,并记录指针位置。
4.交换左右指针的元素。
5.重复上述步骤,直到左边指针大于右边指针结束。
4.代码
public class Quick {
private static boolean less(Comparable v,Comparable w){
return v.compareTo(w)<0;
}
private static void exch(Comparable[] a,int i,int j){
Comparable t=a[i];
a[i]=a[j];
a[j]=t;
}
public static void sort(Comparable[] a){
int low=0;
int high=a.length-1;
sort(a,low,high);
}
private static void sort(Comparable[] a,int low,int high){
if(high<=low){
return;
}
int partition=partition(a,low,high);
//对low到high进行分组,返回分组的分界值所在的索引,分界值变换后的索引
sort(a,low,partition-1);//左边数组有序
sort(a,partition+1,high);//右边数组有序
}
public static int partition(Comparable[] a,int low,int high){
//确定分界值
Comparable key=a[low];
int left=low;
int right=high+1;
while(true){
//先从右往左扫描,找到一个比分界值小的元素就停止
while(less(key,a[--right])){
if(right==low){
break;
}
}
//从左往右扫描,找到一个比分界值大的元素
while(less(a[++left],key)){
if(left==high){
break;
}
}
//判断left是否大于right
if(left>=right){
break;
}else {
exch(a,left,right);
}
}
exch(a,low,right);//交换分界值
return right;//返回分界值所在的索引
}
}
5.快排与归并
1.快速排序会归并排序是互补的,归并排序将数组分成两个子数组进行排序,并将有序的子数组归并从而使整个数组进行排序马,而快排是两个数组有序了整个数组就有序了,归并调用发生在处理整个数组之前,而在快速排序中,切分数组的位置取决于数组的内容,递归调用发生在处理整个数组之后。