原帖 http://www.cnblogs.com/wangjiahong/p/3570465.html?utm_source=tuicool
下面是我直接做成的源码,直接可以运行。
大家可以根据需要测试
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { int[] aa = RandomSet(12, 1024); //int[] aa = OrderedSet(5000); Console.WriteLine("Array Length:" + aa.Length); RunTheMethod((Action<IList<int>>)SelectSort, aa.Clone() as int[]); RunTheMethod((Action<IList<int>>)BubbleSort, aa.Clone() as int[]); RunTheMethod((Action<IList<int>>)BubbleSortImprovedWithFlag, aa.Clone() as int[]); RunTheMethod((Action<IList<int>>)BubbleCocktailSort, aa.Clone() as int[]); RunTheMethod((Action<IList<int>>)InsertSort, aa.Clone() as int[]); RunTheMethod((Action<IList<int>>)InsertSortImprovedWithBinarySearch, aa.Clone() as int[]); RunTheMethod((Action<IList<int>>)QuickSortStrict, aa.Clone() as int[]); RunTheMethod((Action<IList<int>>)QuickSortRelax, aa.Clone() as int[]); RunTheMethod((Action<IList<int>>)QuickSortRelaxImproved, aa.Clone() as int[]); RunTheMethod((Func<IList<int>, IList<int>>)MergeSort, aa.Clone() as int[]); RunTheMethod((Action<IList<int>>)ShellSort, aa.Clone() as int[]); RunTheMethod((Func<IList<int>, IList<int>>)RadixSort, aa.Clone() as int[]); RunTheMethod((Action<IList<int>>)HeapSort, aa.Clone() as int[]); TestMicrosoft(aa.Clone() as int[]); Console.Read(); } public static void RunTheMethod(Func<IList<int>, IList<int>> method, IList<int> data) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); IList<int> result = method(data); stopwatch.Stop(); string methodName = method.Method.Name; int length = methodName.Length; for(int i = 0;i < 40 - length;i++) { methodName += " "; } Console.WriteLine(methodName + " IsAscOrdered:" + IsAscOrdered(result) + " Time:" + stopwatch.Elapsed.TotalSeconds); } public static void RunTheMethod(Action<IList<int>> method, IList<int> data) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); method(data); stopwatch.Stop(); string methodName = method.Method.Name; int length = methodName.Length; for(int i = 0;i < 40 - length;i++) { methodName += " "; } Console.WriteLine(methodName + " IsAscOrdered:" + IsAscOrdered(data) + " Time:" + stopwatch.Elapsed.TotalSeconds); } /***********************************************/ //选择排序 public static void SelectSort(IList<int> data) { for(int i = 0;i < data.Count - 1;i++) { int min = i; int temp = data[i]; for(int j = i + 1;j < data.Count;j++) { if(data[j] < temp) { min = j; temp = data[j]; } } if(min != i) Swap(data, min, i); } } //冒泡排序 public static void BubbleSort(IList<int> data) { for(int i = data.Count - 1;i > 0;i--) { for(int j = 0;j < i;j++) { if(data[j] > data[j + 1]) Swap(data, j, j + 1); } } } //通过标识提升冒泡排序 public static void BubbleSortImprovedWithFlag(IList<int> data) { bool flag; for(int i = data.Count - 1;i > 0;i--) { flag = true; for(int j = 0;j < i;j++) { if(data[j] > data[j + 1]) { Swap(data, j, j + 1); flag = false; } } if(flag) break; } } //鸡尾酒排序(来回排序) public static void BubbleCocktailSort(IList<int> data) { bool flag; int m = 0, n = 0; for(int i = data.Count - 1;i > 0;i--) { flag = true; if(i % 2 == 0) { for(int j = n;j < data.Count - 1 - m;j++) { if(data[j] > data[j + 1]) { Swap(data, j, j + 1); flag = false; } } if(flag) break; m++; } else { for(int k = data.Count - 1 - m;k > n;k--) { if(data[k] < data[k - 1]) { Swap(data, k, k - 1); flag = false; } } if(flag) break; n++; } } } //插入排序 public static void InsertSort(IList<int> data) { int temp; for(int i = 1;i < data.Count;i++) { temp = data[i]; for(int j = i - 1;j >= 0;j--) { if(data[j] > temp) { data[j + 1] = data[j]; if(j == 0) { data[0] = temp; break; } } else { data[j + 1] = temp; break; } } } } //二分查找法优化插入排序 public static void InsertSortImprovedWithBinarySearch(IList<int> data) { int temp; int tempIndex; for(int i = 1;i < data.Count;i++) { temp = data[i]; tempIndex = BinarySearchForInsertSort(data, 0, i, i); for(int j = i - 1;j >= tempIndex;j--) { data[j + 1] = data[j]; } data[tempIndex] = temp; } } public static int BinarySearchForInsertSort(IList<int> data, int low, int high, int key) { if(low >= data.Count - 1) return data.Count - 1; if(high <= 0) return 0; int mid = (low + high) / 2; if(mid == key) return mid; if(data[key] > data[mid]) { if(data[key] < data[mid + 1]) return mid + 1; return BinarySearchForInsertSort(data, mid + 1, high, key); } else // data[key] <= data[mid] { if(mid - 1 < 0) return 0; if(data[key] > data[mid - 1]) return mid; return BinarySearchForInsertSort(data, low, mid - 1, key); } } //快速排序 public static void QuickSortStrict(IList<int> data) { QuickSortStrict(data, 0, data.Count - 1); } public static void QuickSortStrict(IList<int> data, int low, int high) { if(low >= high) return; int temp = data[low]; int i = low + 1, j = high; while(true) { while(data[j] > temp) j--; while(data[i] < temp && i < j) i++; if(i >= j) break; Swap(data, i, j); i++; j--; } if(j != low) Swap(data, low, j); QuickSortStrict(data, j + 1, high); QuickSortStrict(data, low, j - 1); } //快速排序2 public static void QuickSortRelax(IList<int> data) { QuickSortRelax(data, 0, data.Count - 1); } public static void QuickSortRelax(IList<int> data, int low, int high) { if(low >= high) return; int temp = data[(low + high) / 2]; int i = low - 1, j = high + 1; while(true) { while(data[++i] < temp) ; while(data[--j] > temp) ; if(i >= j) break; Swap(data, i, j); } QuickSortRelax(data, j + 1, high); QuickSortRelax(data, low, i - 1); } //快速排序3 public static void QuickSortRelaxImproved(IList<int> data) { QuickSortRelaxImproved(data, 0, data.Count - 1); } public static void QuickSortRelaxImproved(IList<int> data, int low, int high) { if(low >= high) return; int temp = data[(low + high) / 2]; int i = low - 1, j = high + 1; int index = (low + high) / 2; while(true) { while(data[++i] < temp) ; while(data[--j] > temp) ; if(i >= j) break; Swap(data, i, j); if(i == index) index = j; else if(j == index) index = i; } if(j == i) { QuickSortRelaxImproved(data, j + 1, high); QuickSortRelaxImproved(data, low, i - 1); } else //i-j==1 { if(index >= i) { if(index != i) Swap(data, index, i); QuickSortRelaxImproved(data, i + 1, high); QuickSortRelaxImproved(data, low, i - 1); } else //index < i { if(index != j) Swap(data, index, j); QuickSortRelaxImproved(data, j + 1, high); QuickSortRelaxImproved(data, low, j - 1); } } } //归并排序 public static List<int> MergeSortOnlyList(List<int> data, int low, int high) { if(low == high) return new List<int> { data[low] }; List<int> mergeData = new List<int>(); int mid = (low + high) / 2; List<int> leftData = MergeSortOnlyList(data, low, mid); List<int> rightData = MergeSortOnlyList(data, mid + 1, high); int i = 0, j = 0; while(true) { if(leftData[i] < rightData[j]) { mergeData.Add(leftData[i]); if(++i == leftData.Count) { mergeData.AddRange(rightData.GetRange(j, rightData.Count - j)); break; } } else { mergeData.Add(rightData[j]); if(++j == rightData.Count) { mergeData.AddRange(leftData.GetRange(i, leftData.Count - i)); break; } } } return mergeData; } public static List<int> MergeSortOnlyList(List<int> data) { data = MergeSortOnlyList(data, 0, data.Count - 1); //不会改变外部引用 参照C#参数传递 return data; } // IList<int>版本 public static IList<int> MergeSort(IList<int> data) { data = MergeSort(data, 0, data.Count - 1); return data; } public static IList<int> MergeSort(IList<int> data, int low, int high) { int length = high - low + 1; IList<int> mergeData = NewInstance(data, length); if(low == high) { mergeData[0] = data[low]; return mergeData; } int mid = (low + high) / 2; IList<int> leftData = MergeSort(data, low, mid); IList<int> rightData = MergeSort(data, mid + 1, high); int i = 0, j = 0; while(true) { if(leftData[i] < rightData[j]) { mergeData[i + j] = leftData[i++]; //不能使用Add,Array Length不可变 if(i == leftData.Count) { int rightLeft = rightData.Count - j; for(int m = 0;m < rightLeft;m++) { mergeData[i + j] = rightData[j++]; } break; } } else { mergeData[i + j] = rightData[j++]; if(j == rightData.Count) { int leftleft = leftData.Count - i; for(int n = 0;n < leftleft;n++) { mergeData[i + j] = leftData[i++]; } break; } } } return mergeData; } //堆排序 public static void HeapSort(IList<int> data) { BuildMaxHeapify(data); int j = data.Count; for(int i = 0;i < j;) { Swap(data, i, --j); if(j - 2 < 0) //只剩下1个数 j代表余下要排列的数的个数 break; int k = 0; while(true) { if(k > (j - 2) / 2) break; //即:k > ((j-1)-1)/2 超出最后一个父节点的位置 else { int temp = k; k = ReSortMaxBranch(data, k, 2 * k + 1, 2 * k + 2, j - 1); if(temp == k) break; } } } } public static void BuildMaxHeapify(IList<int> data) { for(int i = data.Count / 2 - 1;i >= 0;i--) //(data.Count-1)-1)/2为数列最大父节点索引 { int temp = i; temp = ReSortMaxBranch(data, i, 2 * i + 1, 2 * i + 2, data.Count - 1); if(temp != i) { int k = i; while(k != temp && temp <= data.Count / 2 - 1) { k = temp; temp = ReSortMaxBranch(data, temp, 2 * temp + 1, 2 * temp + 2, data.Count - 1); } } } } public static int ReSortMaxBranch(IList<int> data, int maxIndex, int left, int right, int lastIndex) { int temp; if(right > lastIndex) //父节点只有一个子节点 temp = left; else { if(data[left] > data[right]) temp = left; else temp = right; } if(data[maxIndex] < data[temp]) Swap(data, maxIndex, temp); else temp = maxIndex; return temp; } //希尔排序 public static void ShellSort(IList<int> data) { int temp; for(int gap = data.Count / 2;gap > 0;gap /= 2) { for(int i = gap;i < data.Count;i += gap) { temp = data[i]; for(int j = i - gap;j >= 0;j -= gap) { if(data[j] > temp) { data[j + gap] = data[j]; if(j == 0) { data[j] = temp; break; } } else { data[j + gap] = temp; break; } } } } } //基数排序 public static void BucketSortOnlyUnitDigit(IList<int> data) { int[] indexCounter = new int[10]; for(int i = 0;i < data.Count;i++) { indexCounter[data[i]]++; } int[] indexBegin = new int[10]; for(int i = 1;i < 10;i++) { indexBegin[i] = indexBegin[i - 1] + indexCounter[i - 1]; } IList<int> tempList = NewInstance(data, data.Count); for(int i = 0;i < data.Count;i++) { int number = data[i]; tempList[indexBegin[number]++] = data[i]; } data = tempList; } public static IList<int> RadixSort(IList<int> data) { int max = data[0]; for(int i = 1;i < data.Count;i++) { if(data[i] > max) max = data[i]; } int digit = 1; while(max / 10 != 0) { digit++; max /= 10; } for(int i = 0;i < digit;i++) { int[] indexCounter = new int[10]; IList<int> tempList = NewInstance(data, data.Count); for(int j = 0;j < data.Count;j++) { int number = (data[j] % Convert.ToInt32(Math.Pow(10, i + 1))) / Convert.ToInt32(Math.Pow(10, i)); //得出i+1位上的数 indexCounter[number]++; } int[] indexBegin = new int[10]; for(int k = 1;k < 10;k++) { indexBegin[k] = indexBegin[k - 1] + indexCounter[k - 1]; } for(int k = 0;k < data.Count;k++) { int number = (data[k] % Convert.ToInt32(Math.Pow(10, i + 1))) / Convert.ToInt32(Math.Pow(10, i)); tempList[indexBegin[number]++] = data[k]; } data = tempList; } return data; } ///// public static int[] RandomSet(int length, int max) { int[] result = new int[length]; Random rand = new Random(); for(int i = 0;i < result.Length;i++) { result[i] = rand.Next(max); } return result; } public static bool IsAscOrdered(IList<int> data) { bool flag = true; for(int i = 0;i < data.Count - 1;i++) { if(data[i] > data[i + 1]) flag = false; } return flag; } public static void TestMicrosoft(IList<int> data) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); List<int> result = data.OrderBy(a => a).ToList(); stopwatch.Stop(); string methodName = "TestMicrosoft"; int length = methodName.Length; for(int i = 0;i < 40 - length;i++) { methodName += " "; } Console.WriteLine(methodName + " IsAscOrdered:" + IsAscOrdered(result) + " Time:" + stopwatch.Elapsed.TotalSeconds); } /////////////// public static void Swap(IList<int> data, int a, int b) { int temp = data[a]; data[a] = data[b]; data[b] = temp; } public static int[] OrderedSet(int length) { int[] result = new int[length]; for(int i = 0;i < length;i++) { result[i] = i; } return result; } public static IList<int> NewInstance(IList<int> data, int length) { IList<int> instance; if(data is Array) { instance = new int[length]; } else { instance = new List<int>(length); for(int n = 0;n < length;n++) { instance.Add(0); // 初始添加 } } return instance; } } }