笔者近期在写一个须要计算中位数的功能,而后须要调用数组的排序功能。因而笔者自带的排序功能十分好奇,查了下发现自带的排序其实是应用的快速排序,为了能更好的理解快速排序以及认识其比较合适的使用场景,故手动实现并记录下来:算法
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApp1 { class Program { static int[] test = new int[] {6,1,4,3,5,8 }; /// <summary> /// 一遍 快速排序 /// </summary> /// <param name="a">待排数组</param> /// <param name="low">排序起始值</param> /// <param name="high">排序最高值</param> /// <returns>中枢值位置</returns> public static int Partition(ref int[] a,int low,int high) { // 设置中枢值 int pivotkey = a[low]; // 确保不进入死循环,当low指针大于high叫停 while (low < high) { // 若是high哨兵的值小于中枢值,则将high的值与中枢值调换(中枢值保存了副本pivotkey!) while (low < high && a[high] >= pivotkey) high--; a[low] += a[high]; a[high] = a[low] - a[high]; a[low] -= a[high]; // 若是low哨兵的值大于中枢值,则将low与中枢值调换 while (low < high && a[low] <= pivotkey) low++; a[low] += a[high]; a[high] = a[low] - a[high]; a[low] -= a[high]; } // 结束比对,low和high会碰在一块儿,此时将中枢值副本值插入low的位置 a[low] = pivotkey; return low; } /// <summary> /// 快速排序 /// </summary> /// <param name="a">待排数组</param> /// <param name="low">排序起始值</param> /// <param name="high">排序最高值</param> public static void QuickSort(ref int[] a, int low, int high) { // 加入这个low<high ,一个是确保数组的长度大于1,二是肯定递归结束的条件,防止进入死循环,栈溢出 if (low < high) { // 每次获取中枢值的位置 int pivotloc = Partition(ref a, low, high); // 利用中枢值将每遍排好序的数组分割成两份,接着从low到pivotkey-1 以及 pivotkey+1 到 high两个区域进行排序 // 这里加入比较两端的长度,旨在下降栈的最大深度(下降至logn) if ((pivotloc - low) <= (high - pivotloc)) { QuickSort(ref a, low, pivotloc - 1); QuickSort(ref a, pivotloc + 1, high); } else { QuickSort(ref a, pivotloc + 1, high); QuickSort(ref a, low, pivotloc - 1); } } } static void Main(string[] args) { QuickSort(ref test,0,test.Length-1); foreach (var item in test) { Console.Write(item + " "); } Console.ReadKey(); } } }
资料上显示,快速排序就平均时间而言是目前被认为最好的一种内部排序算法!数组