public class Code_01_Sort
{
public static void main(String[] args)
{
//初始化数组
int len = (int)(Math.random()*20);//随机生成20以内的数组长度
int[] arr = new int[len];
for(int i = 0; i < len; i++)//在数组内随机生成1000内的值
{
arr[i] = (int)(Math.random()*1000) ;
}
for(int i = 0; i < len; i++)//格式化输出排序前数组
System.out.printf("%02d:%-4d\n",i,arr[i]);
quickSort(arr);//调用快速排序
for(int i = 0; i < len; i++)//格式化输出排序后数组
System.out.printf("%02d:%-+4d\n",i,arr[i]);
}
public static void quickSort(int[] arr)//经典快速排序,取最后一个数
{//这个函数主要用来统一函数接口,quickSortProcess才是归并排序
System.out.println("快速排序:");
if(arr == null || arr.length<2)
return;
quickSortProcess(arr,0,arr.length-1);
}
public static void quickSortProcess(int[] arr, int l, int r)
{//快排的思想是把数组分为三部分,小于数组最后一个元素的,等于数组最后一个元素的,大于数组最后一个元素的,然后递归下去
if(l<r)//只要子数组的长达大于1,就递归下去
{
int rIndex = ((int)(Math.random()*(r-l+1)))+l;//变成随机快速排序
int tmp = arr[rIndex];//随机选一个数与数组最后一个数交换
arr[rIndex] = arr[r];
arr[r] = tmp;
int p[] = partition(arr,l,r);
quickSortProcess(arr,l,p[0]-1);//递归左右两部分
quickSortProcess(arr,p[1]+1,r);
}
}
public static int[] partition(int[] arr, int l, int r)
{
int rightest = arr[r];//保存数组最右边的值
int less = l-1;//表示小区的位置,在这个索引(包含此索引)的左边对应的值是小于数组最后一个值的。
int more = r+1; //表示大区的位置在这个索引(包含此索引)的右对应的值是大于数组最后一个值的。
while(l < more)//遍历数组,直到与大区相遇
{
if(arr[l] < rightest)//如果数组里的元素小于数组最右一个元素
{
int tmp = arr[l];//将该元素与小区右一位元素交换位置
arr[l] = arr[less+1];
arr[less+1] = tmp;
less++;//然后小区的范围向右拓展1个位置
l++;//继续遍历下一个元素
}
else if(arr[l] == rightest)//如果数组里的元素等于数组最右一个元素
l++;//则跳过它
else//如果数组里的元素大于数组最右一个元素
{
int tmp = arr[l];//将该元素与大区左一位元素交换位置
arr[l] = arr[more-1];
arr[more-1] = tmp;
more--;//然后大区的范围向左拓展1个位置
}
}
return (new int[]{less+1,more-1});//返回等于区域的索引范围
}
}