JAVA实现快速排序
快速排序思想是通过选取一个"基"(枢轴),使得这个基的左边都是不大于这个基的数,基的右边都是不小于这个基的数。然后再对左右两边递归,直到所有序列有序。主要写一下代码实现的细节。(以从小到大顺序排列)
最关键的部分就是递归部分,每次递归就是将第i至第j个元素进行快排,i到基-1的数小于基,基+1到j的数大于基。
private static void mSort(int[] nums, int low, int high) {
//终止情况,当low等于high时,表明只传入了一个数
//当low大于high时,表明传入了空,也是不需要再快排的情况
//当low小于high,就算是只有两个数也需要排序
if(low>=high){
return;
}
//l和h是储存当前的范围,因为本次快排后这个范围会变为两个范围
//第一个范围就是l到基-1
//第二个范围就是基+1到h
int l = low;
int h = high;
//我没有用交换来做,而是用的"填坑"方法来交换元素,最后填基的值
int temp = nums[low];
//用来保证这一次快排执行完毕,
//当low<high还有元素未和基比较
//这里的low<high代表这一次的快速排序还没有排完
//即从low到high的元素还没有变为基前面比基小,基后面的比基大
while (low<high){
//先看右边,比基大就前移,表明已经放好了
//这里的low<high是为了不出现错误,因为此时的序列如果已经有序了
//但是由于程序必须执行搜索,赋值等过程,那么就会出现high一直减减
//最后减到比low还小,超过数组索引,为了防止这种情况,所以有low<high
//保证了有序这种情况不出现错误
while (low<high && nums[high]>=temp){
high--;
}
//要么low=high,要么nums[high]<temp
//当nums[high]<temp时,需要填到low的位置
//low和high都是指向需要移动(填)的位置
nums[low] = nums[high];
while (low<high && nums[low]<=temp){
low++;
}
nums[high] = nums[low];
}
//此时i==j,已经将所有元素遍历完了,将基(temp)填回序列
nums[low] = temp;
//更新范围,继续快排
mSort(nums, l, low - 1);
mSort(nums, low + 1, h);
}
整体代码如下:
public class Main {
public static void main(String[] args) {
int[] nums = new int[]{3,54,6,8,27,36,2,2,33,3,27,423,656,232};
int len = nums.length;
mSort(nums,0,len-1);
for(int i:nums)
System.out.println(i);
}
private static void mSort(int[] nums, int low, int high) {
if(low>=high){
return;
}
int l = low;
int h = high;
int temp = nums[low];
while (low<high){
while (low<high && nums[high]>=temp){
high--;
}
nums[low] = nums[high];
while (low<high && nums[low]<=temp){
low++;
}
nums[high] = nums[low];
}
nums[low] = temp;
mSort(nums, l, low - 1);
mSort(nums, low + 1, h);
}
}
输出:
2
2
3
3
6
8
27
27
33
36
54
232
423
656
Process finished with exit code 0