快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为较小和较大的2个子序列,然后递归地排序两个子序列。
步骤为:
挑选基准值:从数列中挑出一个元素,称为"基准"(pivot);
分割:重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(与基准值相等的数可以到任何一边)。在这个分割结束之后,对基准值的排序就已经完成;
递归排序子序列:递归地将小于基准值元素的子序列和大于基准值元素的子序列排序。
递归到最底部的判断条件是数列的大小是零或一,此时该数列显然已经有序。
选取基准值有数种具体方法,此选取方法对排序的时间性能有决定性影响。

public class Quick {
public static void main(String[] args) {
int[] arr={8,4,5,7,1,3,6};//直接复制数组
quick_sort(arr,0,arr.length-1);
print(arr);
}
private static int get_mid(int arr[],int left,int right){
int pivot=arr[left];//自定义排序中心轴,这里把arr[left]存到pivot中去,此时arr[left]为空。pivot相当于一个中间量
while(left<right){//当left与right指针相遇的时候退出循环,双指针遍历结束
while(arr[right]>=pivot && left<right) right--;//right指针从右往左遍历,当arr[right]>=pivot,即满足以pivot为中轴,小放左,大放右的条件时,right指针继续往右遍历。当arr[right]<pivotd的时候,把当前值arr[right]赋给空置arr[left],此时arr[right]成了空值。
arr[left]=arr[right];
while(arr[left]<=pivot && left<right) left++;//到left指针从左往右遍历,当arr[left]<=pivot,即满足以pivot为中轴,小放左,大放右的条件时,left指针继续往左遍历。当arr[left]>pivot的时候,把当前值arr[left]赋给空置arr[right],此时arr[left]成了空值。
arr[right]=arr[left];
}
//经历了上面的循环实现了pivot为中轴,小放左,大放右的格局
arr[left]=pivot;//最后把存放在pivot值放回数组空arr[left]中
return left;//返回中轴所在的下标位置。
}
private static void quick_sort(int[] arr,int left,int right){
if(left<right){
/*将arr[left..right]均分为两部分arr[left..mid]和arr[mid+1..right]
* ,以pivot为中轴,小放左,大放右。这是第一步。*/
int mid =get_mid(arr,left,right);//接收中轴所在的下标位置。
quick_sort(arr,left,mid-1);//递归地对arr[left..mid]进行快速排序,使得左子序列有序
quick_sort(arr,mid+1,right);//递归地对arr[mid+1..right]进行快速排序,使得左子序列有序
}
}
public static void print(int arr[])//封装函打印函数
{
for(int k=0;k<arr.length;k++)
{
System.out.print(arr[k]+" ");
}
}
}
网友评论