快速排序法比冒泡真的难好多,网上的实现方法虽然大同,但是很多还都小异,而且有的还有错的…快速排序法最基础的版本是,从两边选基准值,我就是用的这种方法;秀一点的是从中间选基准值,这个的好处是中间的数可以不用动,只动两边的数。
主要的流程如下:
- 从数列中挑出一个元素,称为 “基准”(我在程序里面写为index);
- 重新排序数列,进行一个叫分区(partition)的操作。从数组两边开始选择元素,如果是选择第0个元素,最左边的元素作为基准,当right–有比基准值小的,将right停下;当left++有比基准值大的,将left停下;将两个元素交换。如果left==right,将其和index交换。在这个分区退出之后,该基准就处于数列的中间位置;
- 递归地将小于基准值元素的子数列和大于基准值元素的子数列排序。
比较麻烦的是处理相等的数,跟冒泡还是选择排序法它们不一样,它的相等要在递归里面去处理,就会变得比较麻烦。
import java.util.Scanner;
public class Test {
//划分数组两边
private static int partition(int[] nums,int left,int right){
int index = left;//将数组的第1位作为基准值,将位置保存下来
int x = nums[left];
left = left+1;//加1,从它的下一个开始
while (left<=right){
//假如右边大于基准值,则右边的数在它该在的地方
while (nums[right]>=x&&left<=right){//用>=处理相等的情况,
// 用<=对应最外循环while的判断条件
right--;
}
//假如左边小于基准值,则左边的数在它该在的地方
while (nums[left]<x&&left<right){
left++;
}
if (left==right) {//相等,找到nums[index]应该在的位置
swap(nums,index,left);
return left;
}
//右边和左边通过上面的循环已经选出两个不应该在它们现在在的地方的数字,将它们交换
if (left<right) {
swap(nums,left,right);
}
}
return left;//返回index
}
//快排递归
private static int[] quicksort(int[] nums,int left,int right){
if (left<right){
int index = partition(nums,left,right);
quicksort(nums,left,index-1);
quicksort(nums,index,right);//为了解决数字相等的情况
}
return nums;
}
private static void swap(int[] arr, int i, int j) {//swap函数
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void main(String[] args) {//主函数直接运行,第一次输入数组个数,第二次为数组内容
Scanner in = new Scanner(System.in);
Test main = new Test();
while (true){
int n = in.nextInt();
int[] nums = new int[n];
for(int i = 0;i<n;i++){
nums[i] = in.nextInt();
}
nums = quicksort(nums,0,nums.length-1);
for(int i = 0;i<n;i++) {
System.out.print(nums[i]+" ");
}}
}
}
我写的时候用了好几个测试数组,最难的是通过的是10个的3 3 5 8 1 2 7 10 3 3。
当然可能还是会有不通过的情况和可以改进的地方,还请不吝赐教,谢谢~