快速排序
快速排序的基本思想就是通过一趟排序将待排序列记录分成独立的两部分,其中一部分记录的是比关键字小的部分,还有一部分是比关键字大的一部分;然后再将这两部分记录继续进行排序,以达到整个序列都是有序的。
动态图部分演示:
单路快速排序
实现:排序传入的是数组范围,起始是0 ~ length-1;我们定义一个 i 角标从第二个元素开始遍历,因为我们默认第一个元素为关键字,但为了避免极端情况,我们将随机找一个值为关键字,然后让其和第一个位置数字交换一下位置;我们只考虑小于的部分,让i遍历,定义一个j表示小于部分,也就是小于部分有几个数字,只要遍历的小于关键字,则让其和j+1进行交换,然后j++,表示小于部分数字增加一个;最后将关键字和j角标的数字也就是小于部分的最后一个数字交换一下;这就完成了一轮排序。一次类推。我们是先左后右递归也就是小于部分,再是不小于部分。
package sort;
import java.util.Arrays;
public class QuickSort01 extends Sort{
public QuickSort01(int[] arr){
super(arr);
}
@Override
public void sort() {
quickSort(0,arr.length-1);
}
private void quickSort(int l, int r) {
if(l>=r){
return;
}
int p = partition(l,r);
quickSort(l,p-1);
quickSort(p+1,r);
}
private int partition(int l, int r) {
swap(l,(int)(Math.random()*(r-l+1)+l));
int v = arr[l];
//l+1~j<v<j+1~i
int j=l;
for(int i=l+1;i<=r;i++){
if(arr[i]<v){
swap(j+1,i);
j++;
}
}
swap(l,j);
return j;
}
}
双路快速排序
双路快速排序它是对单路快速排序的优化,定义连个指针将其分为小于等于和大于等于关键字的两部分;它的代码实现比较简单;开始和单路一样,默认第一个元素为关键字,但为了避免极端情况,我们将随机找一个值为关键字,然后让其和第一个位置数字交换一下位置,假设两个指针为left,right分别从第二个和最后一个开始;也是表示小于等于 ,大于等于的元素个数,只不过对于大于等于是增加一个元素角标是减一;而小于等于是加一;只要遍历的值小于关键字left+1,大于的right减一即可,对于left来说,当值是大于等于则需要让left和right交换一下,对于right来说,当值小于等于关键字则让left和right交换一下;当left>right一轮遍历完,将关键字和right交换一下即完成一轮排序。
package sort;
import java.util.Arrays;
public class QuickSort02 extends Sort{
public QuickSort02(int[] arr){
super(arr);
}
@Override
public void sort() {
quickSort(0,arr.length-1);
}