此笔记仅作本人学习、复习与思考用。(代码参考网络)
规定arr[] = {49, 38, 65, 97, 76, 13, 27}
算法步骤:
1,选择基点,规定基点 = index(通常选择数组第一个数)
2,设置left,right(left代表数组最左即arr[0],right代表数组最右即arr[arr.Length - 1],设置left和right是为了向后向前遍历比较和基点的大小)
3,arr[left] 和 index进行比较,如果arr[left] 大于 index 则放到后面 否则left++ 一直往后找直到找到大于index的值 arr[right] 和 index 进行比较 ,如果arr[right] 小于 index 则放到前面 否则right-- 一直往前找直到找到小于index的值(这样规定的原因取决于这个数组是采取降序排序还是升序排序,现在介绍的升序排序)
4,将设置的基点index 放入当前的数组中间
5,重复 2 ,3,4 步骤直到 left == right
代码示例:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace 排序__高速排序 8 { 9 class Program 10 { 11 public static int[] s = { 49, 38, 65, 97, 76, 13, 27 }; 12 static void Main(string[] args) 13 { 14 FastSort(s, 0, s.Length - 1); 15 Console.ReadKey(); 16 } 17 18 private static int SortUnit(int []arr,int left,int right) 19 { 20 int i = left, j = right; 21 int index = arr[left]; 22 while(left<right) 23 { 24 while (left < right && arr[right] > index) right--; 25 arr[left] = arr[right]; 26 while (left < right && arr[left] <= index) left++; // 修改 27 arr[right] = arr[left]; 28 29 } 30 arr[left] = index; 31 foreach (var item in arr) 32 { 33 Console.Write("{0} ", item); 34 } 35 Console.Write(" "); 36 return left; 37 } 38 39 public static void FastSort(int []s,int left,int right) 40 { 41 if (left >= right) return; 42 int index = SortUnit(s, left, right); 43 FastSort(s, left, index - 1); 44 FastSort(s, index + 1, right); 45 } 46 } 47 }
完成排序的片段:
private static int SortUnit(int []arr,int left,int right) { int i = left, j = right; int index = arr[left]; while(left<right) // @1 { while (left < right && arr[right] > index) right--; arr[left] = arr[right]; while (left < right && arr[left] < index) left++; arr[right] = arr[left]; } arr[left] = index; // @2 foreach (var item in arr) { Console.Write("{0} ", item); } Console.Write(" "); return left; //@4 } public static void FastSort(int []s,int left,int right) //@5 { if (left >= right) return; int index = SortUnit(s, left, right); FastSort(s, left, index - 1); FastSort(s, index + 1, right); }
代码解读:
@1 :该循环是将该数组进行一次排序,排序方式(此处说升序)是 首先从后往前找如果碰到小于index就放到前面,如果不存在这样的数,那么直到left和right相同则停止遍历,从前往后的比较也一样(此处说明一下为什么是先从后往前比较而不是先从前往后比较,这个和选择基点index有关系,因为该例子选择的是数组的第一个元素作为基点index,所以在比较后交换的时候,index就有了保存而不是被覆盖掉,如果要先从前往后比较,那么选择的基点就必须是最后一个元素,这样在arr[right] = arr[left] 赋值的时候,就不会覆盖掉arr[right]原先的值,因为已经被保存)
@2:比较且置换完毕之后,选择将基点作为该数组的中间值,且因为此时left = right 所以 直接返回 left 以便为了切割数组(快速排序是通过分治法即递归来完成排序的,所以需要将原先的数组一分为二,左半边数组重复排序步骤,右半边数组重复排序步骤,直到最终被切割成每个数组的元素只有1个时排序结束)
@5:递归结束条件就是left = right 即 该数组的长度为1 即 原数组切割完毕,index 表示使的原数组进行一次排序,获得@4的值 更好的重复递归步骤
PS:这个算法是比较不稳定的,据说有优化的方法,可以使得该方法出现最坏的情况的几率下降,最坏情况是指时间复杂度为O(n2)的情况,有空再研究
后期优化:在代码标注修改处,从原来的 < 修改成现在的 <= ,原因是当需要排序的数组出现相同的数字的时候,可能会出现死循环的情况的!