1,单路快速排序
原理:
选取一个标定元素,然后通过比较数组元素是否大于该元素或者小于该元素。大于的放在该元素的右边,小于的放在该元素的左边。第二次开始划分时,我们已经用之前的标定元素把此数组分为了两部分,因此需要标定数组的前面部分和后面部分都去进行划分,方法和上面一样,重新在两部分找出两个标定元素划分,直到最后只剩下一个数字为止,如图:
时间复杂度:O(nlongn)
空间复杂度:O(1)
稳定性:不稳定
代码如下:
注:1,首先时sort方法来确定quickSort范围,
2,quickSort方法是判断该数组是否合法,如果是则对数组进行划分, 标定元素为p,然后把p的左边和右边分开,而分开的规则则是在partition方法中。
3,这里本来v选取的是首元素,为避免时间复杂度提高,因此选了个随机数,,定义j = L(L是最左边,也就是小于v的域为空),i是用来做遍历的,如果i遍历到一个数小于V,就让新数插入到 j+1处,也就是交换i和 j+1,j覆盖此数,j++ i++。若遍历到一个数大于V,则直接被i覆盖,i++。最后交换L处的v和。
@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]; //arr[l+1 ~ j] < v < arr[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;
2,双路快速排序
比较单路还是简单点。
原理如下: 同样定义L处为v,但是为了防止升序排布,因此该v需要和该数组的某个数交换,确保随机性
代码: swap(L,(int)(Math.random() * (R - L + 1) + L))
定义L+1处为 i,R处为 j ,i++,j–,遍历,当i遍历到自身大于 v时停止,j 遍历到自身小于v时停止,这个时候就可以交换两个数,直到i大于j时遍历停止。
代码如下:
private int partition(int L,int R) {
//优化一下 随机让后面的数字和第一个数字换一下
//尽量避免极端情况(升序情况)
swap(L,(int)(Math.random() * (R - L + 1) + L));
int v = arr[L];
int i = L + 1;
int j = R;
while (true){
while(i <= R && arr[i] < v){
i++;
}
while (j >= L + 1 && arr[j] > v){
j–;
}
if (i > j){
break;
}
swap(i,j);
i++;
j–;
}
swap(L,j);
return j;
}
3,三路快速排序
实现原理:三路排序顾名思义就是三个变量一起遍历,
定义变量:v = arr[L]; lt = L; gt = R + 1; i = L + 1;
具体可以分为下面三种情况:
情况一:arr[i] < v时,swap(i, lt + 1); lt++; i++;
情况二:arr[i] > v时,swap(i, gt - 1); gt–;
情况三:arr[i] = v时,i++
代码如下
@Override
public void sort() {
quickSort(0, arr.length - 1);
}
private void quickSort(int L, int R){
if (L >= R){
return;
}
swap(L, (int) (Math.random() * (R - L + 1) + L));
int v = arr[L];
int lt = L;
int gt = R + 1;
int i = L + 1;
while(i < gt){
if (arr[i] < v){
swap(i, lt + 1);
lt++;
i++;
}else if (arr[i] > v) {
swap(i, gt - 1);
gt–;
}else {
i++;
}
}
swap(L,lt);
quickSort(L,lt - 1);
quickSort(gt,R);