c# 实现快速排序
快速排序的思想是"分而治之"
如果一个数列所有的元素都小于另一个数列的任意元素,那么如果将两个数列排列好,就非常容易合并.
最重要的就是找一个基准(pivot),将数列分裂成比它大的部分,和比它小的部分.
这个pivot数值最好是中间,每次递归,都能化为两个规模类似的问题.
这里采用中值法,第一个,中间位置,最后一个,取中间值.
然后调整序列,使得左边小,右边大,再传出来中间值坐标.
private static int FindMiddle(int[] nums,int left,int right) { int middleIndex = (left + right) / 2; if (nums[left] > nums[middleIndex]) { Swap(nums, left, middleIndex); } if (nums[middleIndex] > nums[right]) { Swap(nums, middleIndex, right); } if (nums[left] > nums[middleIndex]) { Swap(nums, middleIndex, left); } Swap(nums, middleIndex, right - 1); //将倒数第二个元素放到合适的位置,其中左边都比他小,右边都比它大 int i = left;int j = right - 1; while (true) { while (nums[++i] < nums[right - 1]) { }; while (nums[--j] > nums[right - 1]) { }; if (i < j) Swap(nums, i, j); else { Swap(nums, i, right - 1); return i; } } }
解决好这一步,就可以用递归解决了,由于递归非常浪费系统资源,当问题规模较小时,使用其他非递归排序法
private static void QuickSort(int[] nums,int left,int right) { if((right-left)<3)//递归基,真正使用,设置为100左右 { M_InsertSort(nums, left, right); }//用一个插入排序好了 else { int middleIndex= FindMiddle(nums, left, right); QuickSort(nums, left, middleIndex - 1); QuickSort(nums, middleIndex + 1, right); } } private static void M_InsertSort(int[] nums,int left,int right) { if (left == right) return; for(int i = left + 1; i <= right; i++) { int temp = nums[i]; int p = i - 1; while (p>=left&& nums[p] > temp) { nums[p + 1] = nums[p]; p--; } nums[p + 1] = temp; } } public static void Quick_Sort(int[] nums) { QuickSort(nums, 0, nums.Length - 1); }