快速排序的原理:对于一个给定的数组,从中选取一个元素(理论上说可以随意选取一个元素,暂且把这个元素称为中间元素),以这个元素为界,将所有的元素分成两个子集,一个子集中的所有元素都小于中间元素,另一个子集中的所有元素都大于中间元素,此时中间元素就在他最终所在的位置上;对这两个子集分别按照同样的规则再划分成两个子集,直到每一个子集中的元素只有一个或没有为止,这样每次选取的中间元素在每次划分结束之后都处在他最终所在的位置上。所有的划分结束后,所有的元素就都在他最终所在的位置上了。由此可见这个过程是一个递归的过程。
快速排序的关键在于划分,下面介绍三种种划分方法,将数组a[p...r]进行划分。(假定都选取最后一个元素作为中间元素)
从前向后遍历:
partition(a, p, r)
x = p-1;
for i = p to r-1
if a[i] <= a[r]
exchange a[++x] with a[i];
exchange a[i+1] with a[r];
return i + 1;
从后向前遍历
partition(a, p, r)
x = r;
for i = r-1 to p
if a[i] > a[r]
exchange a[i] with a[--x];
exchange a[i+1] with a[r];
return i + 1;
还有一种更容易理解的方式,从数组的两边同时向中间寻找
partition(a, p, r)
i = p - 1;
j = r + 1;
while true
repeat j--;
until a[j] < a[r];
repeat i++;
until a[i] > a[r];
if i < j
exchange a[i] with a[j];
else return j;
具体实现代码如下(partition和quicksort给出了两种实现方式):
<span style="font-size:14px;">package com.hubu.quicksort;
public class QuickSort {
public int partition(int a[], int p, int r) {
int x = (p - 1);
for (int i = p; i < r; i++) {
if (a[i] <= a[r]) {
x += 1;
int temp = a[x];
a[x] = a[i];
a[i] = temp;
}
}
x += 1;
int temp = a[x];
a[x] = a[r];
a[r] = temp;
return x;
}
public int partition_(int a[], int p, int r) {
int x = a[p];
int i = p - 1;
int j = r + 1;
while (true) {
do
j--;
while (a[j] < x);
do
i++;
while (a[i] > x);
if (i < j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
} else
return j;
}
}
public void quick_sort(int a[], int p, int r) {
if (p < r) {
int q = partition_(a, p, r);
quick_sort(a, p, q - 1);
quick_sort(a, q + 1, r);
}
}
public void quick_sort_(int a[], int p, int r) {
while (p < r) {
int q = partition(a, p, r);
quick_sort_(a, p, q - 1);
p = q + 1;
}
}
public static void main(String[] args) {
int a[] = { 5, 6, 3, 6, 14, 1, 2, 4, 2, 4, 7 };
QuickSort qs = new QuickSort();
qs.quick_sort_(a, 0, a.length - 1);
for (int i = 0; i < a.length; i++)
System.out.print(a[i] + " ");
}
}</span>