快速排序
与归并排序相同,快速排序也使用了分治思想。算法设计思路:
分解:假设待排序数组A[p,r],将其划分为两个(可能为空)子数组A[p…q-1]和A[q+1…r],使得A[p…q-1]中的每一个元素都小于等于A[q]而A[q]则小于A[q+1…r]中的每一个元素。计算下标q也是划分过程的一部分
解决:通过递归调用快速排序对子数组进行排序。
合并:因为子数组都是原址排序的,所以不需合并操作。
下面代码为快速排序
Quicksort(A,p,r)
if p < r
q = Partition(A,p,r) //划分方法将数组A[p..r]划分为两部分并返回划分界限的下标。q将不参与子数组的排序
Quicksort(A,p,q-1) //递归快速排序处理划分好的子数组
Quicksort(A,q+1,r)
对于排序数组A的全部数据初始调用为Quicksort(A,1,A.length)
对于快速排序其核心在于对数组的划分即函数Partition
下面代码将实现数组的划分:
Partition(A,p,r)
x = A[r] //选择主元,选择一个元素将其作为划分的依据,这里选择待划分数组的最后一个元素最为方便
i = p-1 //将i指针置在数组的前一位
for j = p to r-1 //遍历数组A[p..r-1]
if A[j]<=x //当一次遍历中遍历元素的值小于等于主元值时
i=i+1 //指针i向前进一
exchange A[i] with A[j] //将A[j]中的元素与A[i]交换
exchange A[i+1] with A[r] //遍历结束后将A[i+1]的值与主元交换,此时一i+1为界限完成了对数组A[p,r]的划分
return i+1 //向排序算法返回划分的界限i+1
对于Partition(A,p,r)算法将数组最后一个元素A[r]的值作为划分依据,遍历数组A[p…r-1],在划分过程中实际上把数组用i,r划分为A[p…i],A[i+1…r-1],A[r]三各部分期中每当遍历检索到一个小于等于A[r]的元素则i自增1A[p…i]长度增加一位并将检索到的元素的值与新增加的元素的值进行交换,在完成整个遍历之后A[p…i]中的元素都小于等于A[r]而A[i+1…r-1]中的元素都大于A[r]。最终将A[r]的值与A[i+1]交换将整个数组变成了一个以A[i+1]为界限划分了的数组,并向上层排序算法返回分界点。
以简单无序数列模拟快速排序,每一次排序的分界值将加粗
5 2 3 4 8 5 9 6 1 7
5 2 3 4 5 6 1 7 8 9
1 2 3 4 5 6 5 7 8 9
1 2 3 4 5 5 6 7 8 9
1 2 3 4 5 5 6 7 8 9
1 2 3 4 5 5 6 7 8 9
1 2 3 4 5 5 6 7 8 9
package QuickSort;
public class QuickSort {
private int[] A;
public int[] getA() {
return A;
}
public void setA(int[] a){
this.A = quickSort(a,0,a.length-1);
}
//快速排序传入参数分别为排序数组,排序区间起始,排序区间末尾。
public int[] quickSort(int[] a,int aStart,int aEnd){
if(quickCheak(a,aStart,aEnd)) {
if (aStart < aEnd) {
int p = partition(a,aStart,aEnd);
quickSort(a,aStart,p-1);
quickSort(a,p+1,aEnd);
}
}
return a;
}
//检测待排序区间是否已有序。
public boolean quickCheak(int[] a,int aStart,int aEnd){
int temp = 0;
for (int i = aStart;i <= aEnd-1;i++){
if(a[i] > a[i+1]){
temp++;
}
}
if(temp != 0){
return true;
}
else {
return false;
}
}
//快速排序核心实现排序区间的划分,将排序区间以标志王牌(joker)划分成两个区间
public int partition(int[] a,int aStart,int aEnd){
int joker = a[aEnd];//将区间终止位的元素作为划分依据joker。
int i = aStart - 1;
for (int j = aStart; j < aEnd;j++){
if(a[j] <= joker){
int temp;
i = i + 1;
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
a[aEnd] = a[i+1];
a[i+1] = joker;
return i+1;
}
}
//测试模块
import QuickSort.QuickSort;
public class Test {
public static void main(String[] args) {
int[] a = {96,38,78,54,14,23,74,12,63,45,41,};
QuickSort q = new QuickSort();
q.setA(a);
for (int p:q.getA()
) {
System.out.println(p);
}
}
}