快速排序
快速排序(Quick Sort)使用分治法策略。
基本思想是:选择一个基准数,通过一趟排序将要排序的数据分割成独立的两部分;其中一部分的所有数据都比基准数小,另外一部分的所有数据都要比基准数大。然后,再按此方法对这两部分数据利用递归方法分别进行快速排序,以此达到整个数据变成有序序列。
快速排序流程:
(1) 从数列中挑出一个基准值。
(2) 将所有比基准值小的摆放在基准前面,所有比基准值大的摆在基准的后面(相同的数可以到任一边);在这个分区退出之后,该基准就处于数列的中间位置。
(3) 递归地把"基准值前面的子数列"和"基准值后面的子数列"进行排序。
int[] arr = new int[10] { 2, 3, 1, 5, 9, 3, 12, 5, 75, 46 };
1 public static void QuickSort(int left, int right) 2 { 3 if (left < right) 4 { 5 int low = left; 6 int high = right; 7 int key = arr[left]; 8 while (low < high) 9 { 10 // 从右向左找第一个小于基数的数 11 while (low < high && arr[high] >= key) 12 high--; 13 if (low < high) 14 arr[low] = arr[high]; 15 16 // 从左向右找第一个大于等于基数的数 17 while (low < high && arr[low] <= key) 18 low++; 19 if (low < high) 20 arr[high] = arr[low]; 21 } 22 arr[low] = key; //此时low=high 23 24 //左右两个分区进行递归调用 25 QuickSort(left, low - 1); 26 QuickSort(high + 1, right); 27 } 28 }
下面以数列a={30,40,60,10,20,50}为例,演示它的快速排序过程(如下图)。
上图只是给出了第1趟快速排序的流程。在第1趟中,设置x=a[i],即x=30。
(01) 从"右 --> 左"查找小于x的数:找到满足条件的数a[j]=20,此时j=4;然后将a[j]赋值a[i],此时i=0;接着从左往右遍历。
(02) 从"左 --> 右"查找大于x的数:找到满足条件的数a[i]=40,此时i=1;然后将a[i]赋值a[j],此时j=4;接着从右往左遍历。
(03) 从"右 --> 左"查找小于x的数:找到满足条件的数a[j]=10,此时j=3;然后将a[j]赋值a[i],此时i=1;接着从左往右遍历。
(04) 从"左 --> 右"查找大于x的数:找到满足条件的数a[i]=60,此时i=2;然后将a[i]赋值a[j],此时j=3;接着从右往左遍历。
(05) 从"右 --> 左"查找小于x的数:没有找到满足条件的数。当i>=j时,停止查找;然后将x赋值给a[i]。此趟遍历结束!
按照同样的方法,对子数列进行递归遍历。最后得到有序数组!