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});//返回等於區域的索引範圍
}
}