快速排序
快速排序就是对荷兰国旗问题的一个递归式应用:
即每次随机取出一个数(在这个数组中等概率随机选一个位置,取出一个数),然后把所有小于这个数的一些值放在左边,等于这个数的一些值放在中间,再把大于这个数的一些值放在右边
在递归的对左边和右边的这批数进行做如上的操作,直到递归到只有一个数为止。
代码及解析:
1 public static void QuickSort(int[] arr) 2 { 3 if (arr == null || arr.length == 1) { 4 return; 5 } 6 process(arr,0,arr.length - 1); 7 } 8 9 public static void process(int[] arr,int l,int r) 10 { 11 if (l < r) {//即当l>=r时都没有继续划分排序的必要,做为递归的终点 12 swap(arr,l + (int)(Math.random() * (r - l + 1)), r);//随机取一个数,把它和最右位置数做交换 13 //即将这个随机数抽出来做参照数 14 int[] p = partition(arr,l,r);//对数组进行三个区域的划分并得到划分的情况 15 //p数组返回两个数分别是小于区域的右边界p[0]和大于区域的左边界p[1] 16 process(arr,l,p[0]);//小于区域 17 process(arr,p[1],r);//大于区域 18 } 19 } 20 21 public static int[] partition(int[] arr,int l,int r) 22 { 23 int minIndex = l - 1, maxIndex = r;//minIndex,maxIndex分别为小于和大于区域的左右边界 24 int curIndex = l;//curIndex为当前被处理的数据所处的位置,以下均为荷兰国旗问题 25 while (curIndex < maxIndex) { 26 if (arr[curIndex] < arr[r]) { 27 swap(arr,curIndex++,++minIndex); 28 } 29 else if (arr[curIndex] == arr[r]) { 30 curIndex++; 31 } 32 else { 33 swap(arr,curIndex,--maxIndex); 34 } 35 } 36 swap(arr,maxIndex++,r);//把arr[r]这个等于num的数给换到等于区域中,并把大于区域右移一位 37 return new int[] {minIndex,maxIndex}; 38 } 39 40 public static void swap(int[] arr,int a,int b) 41 { 42 if (a != b) { 43 arr[a] = arr[a] ^ arr[b]; 44 arr[b] = arr[a] ^ arr[b]; 45 arr[a] = arr[a] ^ arr[b]; 46 } 47 }