排序算法(Sorting algorithm)是计算机科学最古老、最基本的课题之一。要想成为合格的程序员,就必须理解和掌握各种排序算法。
目前,最常见的排序算法大概有七八种,其中"快速排序"(Quicksort)使用得最广泛,速度也较快。它是图灵奖得主C. A. R. Hoare(1934--)于1960时提出来的。
"快速排序"的思想很简单,整个排序过程只需要三步:
(1)在数据集之中,选择一个元素作为"基准"(pivot)。
(2)所有小于"基准"的元素,都移到"基准"的左边;所有大于"基准"的元素,都移到"基准"的右边。
(3)对"基准"左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止。
举例来说,现在有一个数据集{85, 24, 63, 45, 17, 31, 96, 50},怎么对其排序呢?
第一步,选择中间的元素45作为"基准"。(基准值可以任意选择,但是选择中间的值比较容易理解。)
第二步,按照顺序,将每个元素与"基准"进行比较,形成两个子集,一个"小于45",另一个"大于等于45"。
第三步,对两个子集不断重复第一步和第二步,直到所有子集只剩下一个元素为止。
下面我们通过另外一个案例来演示一下快速排序的基本步骤: 以序列 46 30 82 90 56 17 95 15 共8个元素
初始状态: 46 30 82 90 56 17 95 15 选择46 作为基准值,i = 0, j = 7
i = 0 j = 7
15 30 82 90 56 17 95 46 15 < 46, 交换 15 和 46,移动 i, i = 1
i = 1 j = 7
15 30 82 90 56 17 95 46 30 < 46, 不需要交换,移动 i , i = 2
i = 2 j = 7
15 30 46 90 56 17 95 82 82 > 46, 交换82 和 46,移动 j , j = 6
i = 2 j = 6
15 30 46 90 56 17 95 82 95 > 46, 不需要交换,移动 j , j = 5
i = 2 j = 5
15 30 17 90 56 46 95 82 17 < 46, 交换46 和 17,移动 i, i = 3
i = 3 j = 5
15 30 17 46 56 90 95 82 90 > 46, 交换90 和 46,移动 j , j = 4
3 = i j = 4
15 30 17 46 56 90 95 82 56 > 46, 不需要交换,移动 j , j = 3
i = j = 3
i = j = 3, 这样序列就这样分割成了两部分,左边部分{15, 30, 17} 均小于 基准值(46);右边部分 {56, 90,95,82},均大于基准值。这样子我们就达到了分割序列的目标。在接着对子序列用同样的办法进行分割,直至子序列不超过一个元素,那么排序结束,整个序列处于有序状态。
快速排序动画演示
对整个算法总结:
1.i =L; j = R; 将基准数挖出形成第一个坑a[i]。
2.j--由后向前找比它小的数,找到后挖出此数填前一个坑a[i]中。
3.i++由前向后找比它大的数,找到后也挖出此数填到前一个坑a[j]中。
4.再重复执行2,3二步,直到i==j,将基准数填入a[i]中。
5.对两个子集分治排序,直至子序列不超过一个元素,那么排序结束,整个序列处于有序状态。
CODE:
package 排序;
/**
* @version v1.0
* @Package 排序
* @auther LaurenceLau
* @date 2020/4/21,23:33
* @description
*/
import org.junit.Test;
public class QuickSort {
public static int adjustArray(int s[], int l, int r) {//返回调整后基准数的位置
int i = l, j = r;
int x = s[l];//是s[i]即是s[l]就是第一个坑
while (i < j) {
//从右向左找小于X的数来填s[i]
while (i < j && s[j] >= x)
j--;
if (i < j) {
s[i] = s[j];//将s[j]填到s[i]中,s[j]就形成了一个新的坑
i++;
}
//从左向右找大于或等于x的数来填s[j]
while (i < j && s[i] < x)
i++;
if (i < j) {
s[j] = s[i];
j--;
}
}
//退出时,等于j,将x填到这个坑中。
s[i] = x;
return i;
}
//对两个子集采用分治法
public static void quick_sort(int s[], int l, int r) {
if (l < r) {
int i = adjustArray(s, l, r);//先用挖坑填数法调整s[]
quick_sort(s, l, i - 1);//递归调用
quick_sort(s, i + 1, r);
}
}
public static void p(int a[],int n){
for(int i=0;i<n;i++)
System.out.print(a[i]+" ");
}
@Test
public static void main(String[] args) {
int a[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
p(a, 10);
quick_sort(a, 0, 9);//注意最后一个参数是n-1;
System.out.println(" ");
p(a, 10);
}
}