从数列中挑出一个元素,称为 “基准”(pivot);
重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;
这里以3为基准,L为左指针,R为右指针,L找比3大的,R找比3小的
L:2<3 指针向右移动,4>3,找到比3大的了
R:9>3,指针向左移动,1<3,找到比3小的了
替换位置
替换后,L指针向右走,5>3 找到比3大的,R向左走,重叠,5和3换位置
从这里开始,左边的比3小,右边的数比3大,用递归的思维,帮左边的还原,和右边的还原,2>1,找到比1大的,R指针向右移动,重叠,替换位置
替换位置,然后继续3的右边的,4<5,向右移动,跟R指针重叠,替换
代码
在第一次替换位置 L向右走找比它大的,R向左找比它小的,4和1替换
package com.my;
public class QuickSort {
public static void main(String[] args) {
int[] arrs=new int[]{2,4,5,1,9,3};
//先进行简单的拿到基数为3的排序,然后指针L指向左边,R指向右边
int P = arrs.length-1;
int L = 0;
int R = arrs.length-2;
//左边指针找到向右找到比基数大的
while(L<=R && arrs[L]<=arrs[P]){
L++;
}
//右边指针找到向右找到比基数小的
while(L<R &&arrs[R]>=arrs[P]){
R--;
}
//判断,替换位置
if(L<R) {
swap(arrs, L, R);
}else if(L==R){
swap(arrs,L,P);
}
for(int a:arrs){
System.out.print(a);
}
}
private static void swap(int[] arrs, int l, int r) {
int temp = arrs[r];
arrs[r] = arrs[l];
arrs[l] = temp;
}
}
245193
第二次替换位置,L和R相遇时,替换位置,代码有点累赘,可以优化的,思考的过程 3和5替换
package com.my;
public class QuickSort {
public static void main(String[] args) {
int[] arrs=new int[]{2,4,5,1,9,3};
//先进行简单的拿到基数为3的排序,然后指针L指向左边,R指向右边
int P = arrs.length-1;
int L = 0;
int R = arrs.length-2;
//左边指针找到向右找到比基数大的
while(L<=R && arrs[L]<=arrs[P]){
L++;
}
//右边指针找到向右找到比基数小的
while(L<R &&arrs[R]>=arrs[P]){
R--;
}
//判断,替换位置
if(L<R) {
swap(arrs, L, R);
}else if(L==R){
swap(arrs,L,P);
}
//左边指针找到向右找到比基数大的
while(L<=R && arrs[L]<=arrs[P]){
L++;
}
//右边指针找到向右找到比基数小的
while(L<R &&arrs[R]>=arrs[P]){
R--;
}
//判断,替换位置
if(L<R) {
swap(arrs, L, R);
}else if(L==R){
swap(arrs,L,P);
}
for(int a:arrs){
System.out.print(a);
}
}
private static void swap(int[] arrs, int l, int r) {
int temp = arrs[r];
arrs[r] = arrs[l];
arrs[l] = temp;
}
}
213495
第二次替换位置,将代码片段合起来
重复的代码片段
//左边指针找到向右找到比基数大的
while(L<=R && arrs[L]<=arrs[P]){
L++;
}
//右边指针找到向右找到比基数小的
while(L<R &&arrs[R]>=arrs[P]){
R--;
}
//判断,替换位置
if(L<R) {
swap(arrs, L, R);
}else if(L==R){
swap(arrs,L,P);
}
合起来后
package com.my;
public class QuickSort {
public static void main(String[] args) {
int[] arrs=new int[]{2,4,5,1,9,3};
//先进行简单的拿到基数为3的排序,然后指针L指向左边,R指向右边
int P = arrs.length-1;
int L = 0;
int R = arrs.length-2;
while(L<=R){
//左边指针找到向右找到比基数大的
while(L<=R && arrs[L]<=arrs[P]){
L++;
}
//右边指针找到向右找到比基数小的
while(L<R &&arrs[R]>=arrs[P]){
R--;
}
//判断,替换位置
if(L<R) {
swap(arrs, L, R);
}else if(L==R){
swap(arrs,L,P);
}
}
for(int a:arrs){
System.out.print(a);
}
}
private static void swap(int[] arrs, int l, int r) {
int temp = arrs[r];
arrs[r] = arrs[l];
arrs[l] = temp;
}
}
213495
第一大循环结束
现在要3左边的数进行循环,右边的数进行循环,这里可以把上面的合在一起的代码写成一个方法,然后用递归分别去调左边和右边
合在一起的代码写成一个方法
private static int partition(int[] arrs, int l, int r) {
int P = arrs.length-1;
while(l <= r){
//左边指针找到向右找到比基数大的
while(l <= r && arrs[l]<=arrs[P]){
l++;
}
//右边指针找到向右找到比基数小的
while(l < r &&arrs[r]>=arrs[P]){
r--;
}
//判断,替换位置
if(l < r) {
swap(arrs, l, r);
}else if(l == r){
swap(arrs, l,P);
}
}
return P;
}
package com.my;
public class QuickSort {
public static void main(String[] args) {
int[] arrs=new int[]{2,4,5,1,9,3};
//先进行简单的拿到基数为3的排序(最右边),然后指针L指向左边,R指向右边
int L = 0;
int R = arrs.length-1;
sort(arrs,L,R);
for(int a:arrs){
System.out.print(a);
}
}
private static void sort(int[] arrs,int L,int R) {
//结束条件
if(L>=R) return;
//排序,拿到l==R的的位置
int P= partition(arrs, L, R);
//左边排序,递归
sort(arrs,L,P-1);
//右边排序,递归
sort(arrs,P+1,R);
}
private static int partition(int[] arrs, int l, int r) {
int P = r;
r=r-1;
while(l <= r){
//左边指针找到向右找到比基数大的
while(l <= r && arrs[l]<=arrs[P]){
l++;
}
//右边指针找到向右找到比基数小的
while(l < r &&arrs[r]>=arrs[P]){
r--;
}
//判断,替换位置
if(l < r) {
swap(arrs, l, r);
}else if(l == r){
swap(arrs, l,P);
}
}
return l;
}
private static void swap(int[] arrs, int l, int r) {
int temp = arrs[r];
arrs[r] = arrs[l];
arrs[l] = temp;
}
}
123459
优化结构
package com.my;
public class QuickSort {
public static void main(String[] args) {
int[] arrs=new int[]{2,4,5,1,9,3};
//先进行简单的拿到基数为3的排序(最右边),然后指针L指向左边,R指向右边
int L = 0;
int R = arrs.length-1;
sort(arrs,L,R);
for(int a:arrs){
System.out.print(a);
}
}
private static void sort(int[] arrs,int L,int R) {
//结束条件
if(L>=R) return;
int P= partition(arrs, L, R);
//左边排序,递归
sort(arrs,L,P-1);
//右边排序,递归
sort(arrs,P+1,R);
}
//partition 分开
private static int partition(int[] arrs, int L, int R) {
int P = R;
R=R-1;
while(L < R){
//左边指针找到向右找到比基数大的
while(L <= R && arrs[L]<=arrs[P]){
L++;
}
//右边指针找到向右找到比基数小的
while(L < R &&arrs[R]>arrs[P]){
R--;
}
//判断,替换位置
if(L < R) {
swap(arrs, L, R);
}
}
swap(arrs, L,P);
return L;
}
private static void swap(int[] arrs, int l, int r) {
int temp = arrs[r];
arrs[r] = arrs[l];
arrs[l] = temp;
}
}