思想
在学习算法分析的时候,一开始接触的就是递归与分治策略。分治法的基本思想是将一个规模为n的问题分解为k个规模较小的子问题,这些子问题互相独立且与原问题相同。可以递归地解决这些子问题,然后将子问题的解合并最终求得原问题。
这里的快速排序就运用了递归求解的思想
通过一趟扫描将待排序的元素分割成独立的三个部分:
- part1:所有不大于基准元素的元素
- part2:基准元素(pivot)
- part3:所有不小于基准元素的元素
再按照此过程对第一个序列和第三个序列分别进行排序,直到所有元素按顺序排列。
注:此过程可以递归进行
过程
分解
在A[low:high]中选定一个元素作为基准元素(pivot),以此基准元素为标准将待排序列划分为两个子序列。
其中:A[low:pivotpos - 1]中的所有元素的值均小于等于A[pivotpos],序列A[pivotpos + 1:high]中的所有元素的值均大于等于A[pivotpos]。
关键:序列划分
-设待排序列为A[low, high],该划分过程以第一个元素作为基准元素
- 设置两个参数i = A[low]和j = A[high]
- 选取A[low]为基准元素,令pivot = A[low]
- 令 j 从 j 位置开始向左扫描,若A[j] >= pivot则 j 前移一个位置(j - -)。重复该过程,直到A[j] < pivot,此时将A[j] 与 A[i] 进行交换,i++。
- 令 i 从 i 位置开始向右扫描,如果 A[i] <= pivot则 i 向后一个位置(i++)重复该过程,直到找出A[i] > pivot,将A[j] 与 A[i]进行交换,j - -
- 重复3、4步骤,交替改变扫描方向,从两端向中间考虑直到 i = j
此时 i 和 j 指向同一个位置,即基准元素pivot的最终位置
求解子问题
对A[low:pivotpos - 1]和A[pivotpos + 1:high]分别通过递归调用快速排序算法进行排序。
合并
将两个子序列合为一个完整的序列。
伪代码描述
QUICK-SORT(A, LOW, HIGH)
IF low < high
pivotpos = PARTITION(A, low, high) //划分序列
QUICK-SORT(A, low, pivotpos-1) //对左区间递归排序
QUICK-SORT(A, pivotpos+1, high) //对右区间递归排序
PARTITION(A, low, high, pivoIndex)
i = low, j = high, pivot = A[pivotIndex]
WHILE i < j
WHILE i < j AND A[j] >= pivot
j--
IF i < j
SWAP(A, i++, j)
WHILE i < j AND A[i] <= pivot
i++
IF i < j
SWAP(A, i , j--)
代码描述
package test;
public class QuickSortDC {
public static void main(String[] args) {
// TODO 自动生成的方法存根
int a[] = {49, 38, 65, 97, 76, 13, 27};
QuickSortDC.printArray(a);
QuickSortDC.quickSort(a, 0, 6);
QuickSortDC.printArray(a);
}
public static void quickSort(int[] aa, int low, int high) {
if (low < high) {
int pivotpos = QuickSortDC.partitionOnePass(aa, low, high, low); //划分序列
QuickSortDC.quickSort(aa, low, pivotpos-1); //对左区间递归排序
QuickSortDC.quickSort(aa, pivotpos+1, high); //对右区间递归排序
}
}
public static int partitionOnePass(int[] aaa, int low, int high, int pivotIndex) {
int i = low, j = high, pivot = aaa[pivotIndex];
while(i < j) {
while((i < j) && (aaa[j] >= pivot))
{
j --;
}
if(i < j)
{
QuickSortDC.swap(aaa, i++, j);
}
while((i < j) && (aaa[i] <= pivot))
{
i ++;
}
if(i < j)
{
QuickSortDC.swap(aaa, i, j--);
}
}
return j;
}
public static void swap(int[] aaaa, int i, int j) {
int iTemp = aaaa[i];
aaaa[i] = aaaa[j];
aaaa[j] = iTemp;
}
public static void printArray(int a5[]) {
System.out.println();
for(int i = 0; i < a5.length; i ++)
System.out.print("\t" + a5[i]);
System.out.println();
}
}