快速排序算法的C#实现
原文链接:http://www.cnblogs.com/heyuquan/p/bubble-quick-sort.html
完整可运行的控制台应用程序源码:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace algorithm 7 { 8 class Program 9 { 10 public enum QuickType { Normal = 1, Random, Balance }; 11 12 private static Random random = null; 13 14 /// <summary> 15 /// 程序入口 16 /// </summary> 17 /// <param name="args"></param> 18 private static void Main(string[] args) 19 { 20 Console.Title = "快速排序测试"; 21 22 int size = 30000000;//随机数组大小,可修改 23 int max = 10000000;//随机数的上界,可修改 24 int[] array = new int[size]; 25 26 //产生随机数组 27 Random rdm = new Random(); 28 for (int i = 0; i < size; i++) 29 { 30 array[i] = rdm.Next(1, max); 31 } 32 33 //输出随机数组 34 for (int j = 0; j < size; j++) 35 { 36 Console.Write(array[j] + "\t"); 37 if ((j + 1) % 10 == 0) 38 { 39 Console.WriteLine(); 40 } 41 } 42 43 Console.ReadLine(); 44 //对数组做排序处理 45 Sort(array, QuickType.Normal); //采用快速排序,可修改 46 47 //输出排序后的随机数组 48 for (int j = 0; j < size; j++) 49 { 50 Console.Write(array[j] + "\t"); 51 if ((j + 1) % 10 == 0) 52 { 53 Console.WriteLine(); 54 } 55 } 56 Console.ReadLine(); 57 } 58 59 /// <summary> 60 /// 优化的快速排序 61 /// </summary> 62 /// <param name="arr">待排序数组</param> 63 /// <param name="quickType">排序算法</param> 64 public static void Sort<T>(IList<T> arr, QuickType quickType = QuickType.Normal) where T : IComparable<T> 65 { 66 if (arr == null) 67 { 68 throw new ArgumentNullException("arr"); 69 } 70 switch (quickType) 71 { 72 case QuickType.Normal: // 快速排序 73 { 74 DoSort<T>(arr, 0, arr.Count() - 1, 75 (subArr, left, right) => 76 { 77 // 默认以第1个数为基数。 78 // 所以,什么都不用做 79 } 80 ); 81 } 82 break; 83 case QuickType.Random: // 随机快排 84 { 85 DoSort<T>(arr, 0, arr.Count() - 1, 86 (subArr, left, right) => 87 { 88 if (subArr.Count > 10) 89 { 90 // 随机化快排:随机数组中一个元素做基准 91 if (random == null) 92 random = new Random(new Guid().GetHashCode()); 93 int index = random.Next(left, right); 94 95 T temp = subArr[left]; 96 subArr[left] = subArr[index]; 97 subArr[index] = temp; 98 } 99 } 100 ); 101 } 102 break; 103 case QuickType.Balance: // 平衡快排 104 { 105 DoSort<T>(arr, 0, arr.Count() - 1, 106 (subArr, left, right) => 107 { 108 if (subArr.Count > 10) 109 { 110 int index = -1; 111 // 平衡快排:取开头、结尾、中间3个数据,通过比较选出其中的中值 112 int middle = (left + right) / 2; 113 114 // 取较小的数 115 if (subArr[middle].CompareTo(subArr[left]) >= 0) 116 { 117 index = left; 118 } 119 else 120 { 121 index = middle; 122 } 123 124 // 再用较小的数去比较 125 if (subArr[index].CompareTo(subArr[right]) >= 0) 126 { 127 // 那么index就是中间元素 128 } 129 else 130 { 131 // index为最小元素,中间元素在left和right中 132 if (subArr[right].CompareTo(subArr[left]) >= 0) 133 { 134 index = left; 135 } 136 else 137 { 138 index = right; 139 } 140 } 141 142 // 交换 143 T temp = subArr[left]; 144 subArr[left] = subArr[index]; 145 subArr[index] = temp; 146 } 147 } 148 ); 149 } 150 break; 151 } 152 } 153 154 /// <summary> 155 /// 快速排序 156 /// </summary> 157 /// <param name="arr">待排序数组</param> 158 /// <param name="left">左边界索引</param> 159 /// <param name="right">右边界索引</param> 160 /// <param name="SelectPivot">选择基准元素委托,并且将基元素与左边界元素交换</param> 161 private static void DoSort<T>(IList<T> arr, int left, int right 162 , Action<IList<T>, int, int> SelectPivot) where T : IComparable<T> 163 { 164 if (left < right) 165 { 166 // 选择基准元素委托 167 if (SelectPivot != null) 168 SelectPivot(arr, left, right); 169 170 // 临时存储基准元素,以让其他数组元素来填充该位置 171 T pivot = arr[left]; 172 int low = left; 173 int high = right; 174 175 while (low < high) 176 { 177 // 从右向左找第一个小于 基数 的数 178 while (low < high && arr[high].CompareTo(pivot) >= 0) 179 high--; 180 if (low < high) 181 arr[low++] = arr[high]; 182 183 // 从左向右找第一个大于等于 基数 的数 184 while (low < high && arr[low].CompareTo(pivot) < 0) 185 low++; 186 if (low < high) 187 arr[high--] = arr[low]; 188 } 189 arr[low] = pivot; // 此时 low = high 190 191 // 两个分区递归。基准元素无需在参与下一次快速排序 192 DoSort<T>(arr, left, low - 1, SelectPivot); 193 DoSort<T>(arr, low + 1, right, SelectPivot); 194 } 195 } 196 } 197 }