分治法的基本思想(Divide-and-Conquer):
将原问题分解为若干个规模更小,但结构与原问题相同的子问题。递归的解决这些子问题,然后将这些子问题的解组合成原问题的解。
快速排序基本思想:
快速排序是一种划分交换排序,它的基本思想是,通过一趟排序将记录分割成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,然后用递归的方法再分别对分割所得的两个子序列进行快速排序。
设当前待排序的序列为R[low...high],利用分治法可以将快速排序的基本思想描述为:
1. 分解:
在R[low...high]中任选一个记录(通常选第一个记录)作为基准(pivot),以此基准将当前无序序列划分为左,右两个较小的子区间R[low...pivotpos-1]和[pivotpos+1...high],左边子区间中所有记录的关键字均小于或等于基准记录的关键字pivot.key, 右边子区间中所有记录的关键字均大于或等于基准记录的关键字pivot.key, 而基准记录pivot则位于正确的位置上pivotpos,无须参加后续的排序。划分的关键是要求出基准记录的位置pivotpos.
2. 求解:
通过递归调用快速排序,对左,右子区间进行快速排序。
3. 组合:
因为当“求解”步骤中的两个递归调用结束时,其左,右两个子区间已经有序。所以对快速排序而言,"组合"步骤什么也不用做。
划分算法 Partition:
1. 初始化:设置两个指针i和j,他们的初始值分别为区间的下界和上界,即i=low, j=high。选取无序区间的第一个记录R[i](即R[low])作为基准记录,并将它保存在变量pivot中。
2. 令j自high起向左扫描,直到找到第1个关键字小于pivot的记录R[j], 将R[j]和基准R[i]进行交换,交换后,R[j]中存放了pivot
3. 然后令i指针自i+1的位置开始向右扫描,直到找到第一个关键字大于pivot的记录R[i],将R[i]和基准R[j]进行交换,交换后R[i]中又存放了pivot
4. 接着令指针j自位置j-1开始向左扫描,如此交替改变扫描方向,直至i=j时,i便是基准pivot最终的位置,就完成了一次划分
快速排序的时间复杂度:
快速排序是一种不稳定的排序方法。其平均时间复杂度为O(nlgn), 最差情况下时间复杂度为O(n2)。
JAVA实现的快速排序:
//对source快速排序
public class QuickSort {
public static void quickSort(int source[], int low, int high) {
int pivotpos; //划分后的基准记录的位置
if(low<high) { //仅当区间长度大于1时才排序
pivotpos = Partition(source, low, high); //对source[low...high]做划分
quickSort(source,low,pivotpos-1); //对左区间递归排序
quickSort(source,pivotpos+1,high); //对右区间递归排序
}
}
//调用Partition(source,low,high)时,对source(low,high)做划分,并返回基准记录的位置
public static int Partition(int[] source, int low, int high) {
int pivot = source[low]; //用区间的第一个记录作为基准
while(low < high) { //从区间两端交替向中间扫描,直至 i=j 为止
while(low<high && source[high]>pivot) { //pivot的位置在i上
high--;
}
swap(source,low,high); //找到了关键字小于pivot的source[j],交换source[i]和source[j]
while(low<high && source[low]<pivot) { //pivot的位置在j上
low++;
}
swap(source,low,high); //找到了关键字大于pivot的source[i],交换source[i]和source[j]
}
return low;
}
public static void swap(int source[], int i, int j) {
int temp;
temp = source[i];
source[i] = source [j];
source[j] = temp;
}
//测试上面的quickSort方法
public static void main(String[] args) {
int test[] = {49,38,65,97,76,13,27};
quickSort(test,0,6);
for(int i=0; i<test.length;i++) {
System.out.println(test[i]);
}
}
}
输出结果:
13
27
38
49
65
76
97