三指针分区思路:与单向扫描分区类似只不过三指针分区把与主元相等的分成一个区间。所以和单向扫描一样有一个扫描指针和末指针。多的一个equal指针用来指向与主元相等区间的首元素。
最开始的时候第一个元素为主元,e(equal指针),s(扫描指针),b(末指针)
与单向扫描一样,通过判断扫描指针所指的元素大小
如果等于主元 S(扫描指针)右移一个
如果小于主元 e和s的位置交换,e++,s++
如果大于主元 s和b交换,b--
这样就会形成下面的局面
代码
import java.util.Arrays;
import lanqiao.Swap;
public class 快排之三指针分区法 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int arr[] = new int[5];
Swap.ArryRandom(arr, 5);//这里是自己写的一个产生随机数组的方法
System.out.println(Arrays.toString(arr));
quicksort(arr,0,arr.length-1);
System.out.println(Arrays.toString(arr));
}
public static void quicksort(int[] arr, int start, int end) {
if(start<end) {
int w[] = partition(arr,start,end);//找到主元数组下标
quicksort(arr,start,w[0]-1);//对左边进行快排,
quicksort(arr,w[1]+1,end);//对右边进行快排
}
}
public static int[] partition(int[] arr,int start,int end) {
int zhuyuan = arr[start];//主元
int eq = start+1;//指向与主元相等的数组的首地址
int left = start+1;//小于主元 左指针
int right = end;//大于主元 右指针
while(left<=right) {
//小于主元左指针右移,eq++;先交换值
if(arr[left]<zhuyuan) {
Swap.swap(arr, eq, left);
left++;
eq++;
}
//等于主元e,左指针右移
else if(arr[left]==zhuyuan) {
left++;
}
//大于主元,与右指针交换值;右指针左移
else if(arr[left]>zhuyuan) {
Swap.swap(arr, left, right);
right--;
}
}
Swap.swap(arr, start, eq-1);
int q1 = eq--;
int q2 = right;
int fanhui[]= {q1,q2};
return fanhui;
}
}