在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
选择排序using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace sorter { public class SelectionSorter { private int min; public void Sort(int[] arr) { for (int i = 0; i < arr.Length - 1; ++i) { min = i; for (int j = i + 1; j < arr.Length; ++j) { if (arr[j] < arr[min]) { min = j; } } int t = arr[min]; arr[min] = arr[i]; arr[i] = t; } } } class Program { static void Main(string[] args) { int[] arrInt = new int[] { 4, 2, 7, 1, 8, 3, 9, 0, 5, 6 }; SelectionSorter selSor = new SelectionSorter(); selSor.Sort(arrInt); foreach (int i in arrInt) { Console.WriteLine(i); } Console.ReadKey(); } } } 冒泡排序using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace sorter { public class EbullitionSorter { public void Sort(int[] arr) { int i, j, temp; bool done = false; j = 1; while ((j < arr.Length) && (!done)) // 推断长度 { done = true; for (i = 0; i < arr.Length - j; i++) { if (arr[i] > arr[i + 1]) { done = false; temp = arr[i]; arr[i] = arr[i + 1]; // 交换数据 arr[i + 1] = temp; } } j++; } } } class Program { static void Main(string[] args) { int[] arrInt = new int[] { 4, 2, 7, 1, 8, 3, 9, 0, 5, 6 }; EbullitionSorter selSor = new EbullitionSorter(); selSor.Sort(arrInt); foreach (int i in arrInt) { Console.WriteLine(i); } Console.ReadKey(); } } } 高速排序using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace sorter { public class QuickSorter { private void swap(ref int l, ref int r) { int temp; temp = l; l = r; r = temp; } public void Sort(int[] list, int low, int high) { int pivot; // 存储分支点 int l, r; int mid; if (high <= low) { return; } else if (high == low + 1) { if (list[low] > list[high]) { swap(ref list[low], ref list[high]); } return; } mid = (low + high) >> 1; pivot = list[mid]; swap(ref list[low], ref list[mid]); l = low + 1; r = high; do { while (l <= r && list[l] < pivot) { l++; } while (list[r] >= pivot) { r--; } if (l < r) { swap(ref list[l], ref list[r]); } } while (l < r); list[low] = list[r]; list[r] = pivot; if (low + 1 < r) { Sort(list, low, r - 1); } if (r + 1 < high) { Sort(list, r + 1, high); } } } class Program { static void Main(string[] args) { int[] arrInt = new int[] { 4, 2, 7, 1, 8, 3, 9, 0, 5, 6 }; QuickSorter selSor = new QuickSorter(); selSor.Sort(arrInt, 0, arrInt.Length - 1); foreach (int i in arrInt) { Console.WriteLine(i); } Console.ReadKey(); } } } 插入排序using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace sorter { public class InsertionSorter { public void Sort(int[] arr) { for (int i = 1; i < arr.Length; i++) { int t = arr[i]; int j = i; while ((j > 0) && (arr[j - 1] > t)) { arr[j] = arr[j - 1]; // 交换顺序 --j; } arr[j] = t; } } } class Program { static void Main(string[] args) { int[] arrInt = new int[] { 4, 2, 7, 1, 8, 3, 9, 0, 5, 6 }; InsertionSorter selSor = new InsertionSorter(); selSor.Sort(arrInt); foreach (int i in arrInt) { Console.WriteLine(i); } Console.ReadKey(); } } } 希尔排序using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace sorter { public class ShellSorter { public void Sort(int[] arr) { int inc; for (inc = 1; inc <= arr.Length / 9; inc = 3 * inc + 1) ; for (; inc > 0; inc /= 3) { for (int i = inc + 1; i <= arr.Length; i += inc) { int t = arr[i - 1]; int j = i; while ((j > inc) && (arr[j - inc - 1] > t)) { arr[j - 1] = arr[j - inc - 1]; // 交换数据 j -= inc; } arr[j - 1] = t; } } } } class Program { static void Main(string[] args) { int[] arrInt = new int[] { 4, 2, 7, 1, 8, 3, 9, 0, 5, 6 }; ShellSorter selSor = new ShellSorter(); selSor.Sort(arrInt); foreach (int i in arrInt) { Console.WriteLine(i); } Console.ReadKey(); } } } 归并排序using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Merge { public class Function { private int Groups; private int CopyGroups; private int mergerows; private int[] Array27; private static Random ran = new Random(); public Function(int length) { Array27 = new int[length]; for (int i = 0; i < length; i++) Array27[i] = ran.Next(1, 100); } //选择 public void ToMergeSort() { MergeSort(Array27); } public void ToRecursiveMergeSort() { RecursiveMergeSort(Array27, 0, Array27.Length - 1); } public void ToNaturalMergeSort() { NaturalMergeSort(Array27); } /// <summary> /// 归并排序(递归) /// 核心思想:(分治) /// 将待排序元素(递归直至元素个数为1)分成左右两个大小大致同样的2个子集合。然后。 /// 分别对2个子集合进行排序,终于将排好序的子集合合并成为所要求的排好序的集合. /// 核心算法时间复杂度: /// T(n)=O(nlogn) /// </summary> /// <param name="Array"></param> /// <param name="left"></param> /// <param name="right"></param> public void RecursiveMergeSort(int[] Array, int left, int right) { int middle = (left + right) / 2; if (left < right) { //对前半部分递归拆分 RecursiveMergeSort(Array, left, middle); //对后半部分递归拆分 RecursiveMergeSort(Array, middle + 1, right); MergeOne(Array, left, middle, right); } } public void MergeOne(int[] Array, int left, int middle, int right) { int leftindex = left; int rightindex = middle + 1; //动态暂时二维数组存放切割为两个小Array的数组排列顺序后的数据 int[] merge = new int[right + 1]; int index = 0; //对两个小数组合并排序 while (leftindex <= middle && rightindex <= right) merge[index++] = (Array[leftindex] - Array[rightindex]) >= 0 ? Array[rightindex++] : Array[leftindex++]; //有一側子数列遍历完后,将另外一側子数列剩下的数依次放入暂存数组中(有序) if (leftindex <= middle) { for (int i = leftindex; i <= middle; i++) merge[index++] = Array[i]; } if (rightindex <= right) { for (int i = rightindex; i <= right; i++) merge[index++] = Array[i]; } //将有序的数列 写入目标数组 ,即原来把Array数组分为两个小Array数组后又一次有序组合起来(覆盖原数组) index = 0; for (int i = left; i <= right; i++) Array[i] = merge[index++]; } /// <summary> /// 归并排序(非递归) /// 核心思想:(分治) /// 对n个数的数列每相邻两个元素排序。组成n/2个或(n+1)/2个子数组,单个的不比了直接进入下一轮。 /// 然后对每一个相邻的子数组再排序,以此类推最后得到排好序的数列 /// forexample: 59 35 54 28 52 /// 排序And分: 35 59. 28 54. 52 /// 排序And分: 28 35 54 59. 52 /// 结果: 28 35 52 54 59 /// 核心算法时间复杂度: /// T(n)=O(nlogn) /// </summary> /// <param name="Array"></param> public void MergeSort(int[] Array) { //index固定的数组 int[] merge = new int[Array.Length]; int P = 0; while (true) { int index = 0; //子数组元素的个数 int ENumb = (int)Math.Pow(2, P); //一个子数组中的元素个数与数组的一半元素个数比較大小 //最糟糕的情况最右边的数组仅仅有一个元素 if (ENumb < Array.Length) { while (true) { int TorFAndrightindex = index; //最后一个子数组的第一个元素的index与数组index相比較 if (TorFAndrightindex <= Array.Length - 1) MergeTwo(Array, merge, index, ENumb); else break; index += 2 * ENumb; } } else break; P++; } } public void MergeTwo(int[] Array, int[] merge, int index, int ENumb) { //换分两个子数组的index(千万不能用middle = (right + left) / 2划分) // 1 int left = index; int middle = left + ENumb - 1; //(奇数时) //排除middleindex越界 if (middle >= Array.Length) { middle = index; } //同步化merge数组的index int mergeindex = index; // 2 int right; int middleTwo = (index + ENumb - 1) + 1; right = index + ENumb + ENumb - 1; //排除最后一个子数组的index越界. if (right >= Array.Length - 1) { right = Array.Length - 1; } //排序两个子数组并拷贝到merge数组 while (left <= middle && middleTwo <= right) { merge[mergeindex++] = Array[left] >= Array[middleTwo] ? Array[middleTwo++] : Array[left++]; } //两个子数组中当中一个比較完了(Array[middleTwo++] 或Array[left++])。 //把当中一个数组中剩下的元素复制进merge数组。 if (left <= middle) { //排除空元素. while (left <= middle && mergeindex < merge.Length) merge[mergeindex++] = Array[left++]; } if (middleTwo <= right) { while (middleTwo <= right) merge[mergeindex++] = Array[middleTwo++]; } //推断是否合并至最后一个子数组了 if (right + 1 >= Array.Length) Copy(Array, merge); } /// <summary> /// 自然归并排序: /// 对于初始给定的数组,通常存在多个长度大于1的已自然排好序的子数组段. /// 比如,若数组a中元素为{4,8,3,7,1,5,6,2},则自然排好序的子数组段 /// 有{4,8},{3,7},{1,5,6},{2}. /// 用一次对数组a的线性扫描就足以找出全部这些排好序的子数组段. /// 然后将相邻的排好序的子数组段两两合并, /// 构成更大的排好序的子数组段({3,4,7,8},{1,2,5,6}). /// 继续合并相邻排好序的子数组段,直至整个数组已排好序. /// 核心算法时间复杂度: /// T(n)=○(n); /// </summary> public void NaturalMergeSort(int[] Array) { //得到自然划分后的数组的index组(每行为一个自然子数组) int[,] PointsSymbol = LinearPoints(Array); //子数组仅仅有一个。 if (PointsSymbol[0, 1] == Array.Length - 1) return; //多个(至少两个子数组)... else //能够堆栈调用吗? NaturalMerge(Array, PointsSymbol); } public void NaturalMerge(int[] Array, int[,] PointsSymbol) { int left; int right; int leftend; int rightend; mergerows = GNumberTwo(Groups); CopyGroups = Groups; //固定状态 int[] TempArray = new int[Array.Length]; //循环取每一个自然子数组的index while (true) { // int Temprow = 1; //仅仅记录合并后的子数组(”《应该为》“动态的) int[,] TempPointsSymbol = new int[mergerows, 2]; int row = 0; do { //最重要的推断:最后(一组子数组)是否可配对 if (row != CopyGroups - 1) { //以上条件也能够含有(& 和&&的差别)短路运算 //參考:http://msdn.microsoft.com/zh-cn/library/2a723cdk(VS.80).aspx left = PointsSymbol[row, 0]; leftend = PointsSymbol[row, 1]; right = PointsSymbol[row + 1, 0]; rightend = PointsSymbol[row + 1, 1]; MergeThree(Array, TempArray, left, leftend, right, rightend); MergePointSymbol(PointsSymbol, TempPointsSymbol, row); } else { ////默认剩下的单独一个子数组已经虚拟合并。然后Copy进TempArray。 int TempRow = PointsSymbol[row, 0]; int TempCol = PointsSymbol[row, 1]; while (TempRow <= TempCol) TempArray[TempRow] = Array[TempRow++]; //TempPointSymbol完整同步 TempPointsSymbol[row / 2, 0] = PointsSymbol[row, 0]; TempPointsSymbol[row / 2, 1] = PointsSymbol[row, 1]; break;//又一次開始新一轮循环。 } row += 2; // Temprow++; //合并到仅仅有一个子数组时结束循环 if (TempPointsSymbol[0, 1] == Array.Length - 1) break; }//推断别进入越界循环(能够进孤单循环)这里指的是PointsSymbol的子数组个数 while (row <= CopyGroups - 1); // Copy(Array, TempArray); //更新子数组index,row为跳出循环的条件(最后单个子数组或下一个越界的第一个) UpdatePointSymbol(PointsSymbol, TempPointsSymbol, row); //改变TempPointsSymbol的行数(合并后子数组数) mergerows = GNumber(mergerows); CopyGroups = GNumberTwo(CopyGroups); //合并到仅仅有一个子数组时结束循环 if (PointsSymbol[0, 1] == Array.Length - 1) break; } //输出 } public int GNumber(int Value) { if (Value % 2 == 0) Value /= 2; else Value -= 1; return Value; } public int GNumberTwo(int Value) { if (Value % 2 == 0) mergerows = Value / 2; else mergerows = Value / 2 + 1; return mergerows; } public void MergeThree(int[] Array, int[] Temp, int left, int leftend, int right, int rightend) { //合并语句 int index = left; while (left <= leftend && right <= rightend) Temp[index++] = Array[left] >= Array[right] ? Array[right++] : Array[left++]; while (left <= leftend) Temp[index++] = Array[left++]; while (right <= rightend) Temp[index++] = Array[right++]; } public void MergePointSymbol(int[,] PointsSymbol, int[,] TempPointsSymbol, int row) { int rowindex = row / 2; TempPointsSymbol[rowindex, 0] = PointsSymbol[row, 0]; TempPointsSymbol[rowindex, 1] = PointsSymbol[row + 1, 1]; } public void UpdatePointSymbol(int[,] PointsSymbol, int[,] TempPointsSymbol, int rows) { int row = 0; //if (mergerows % 2 == 0) //{ for (; row < TempPointsSymbol.GetLength(0); row++) { for (int col = 0; col < 2; col++) PointsSymbol[row, col] = TempPointsSymbol[row, col]; } //后面的清零 for (; row < PointsSymbol.GetLength(0); row++) { for (int col2 = 0; col2 < 2; col2++) PointsSymbol[row, col2] = 0; } //} ////补剩下的index组, //else //{ // for (int row2 = 0; row2 < TempPointsSymbol.GetLength(0); row2++) // { // for (int col3 = 0; col3 < 2; col3++) // PointsSymbol[row2, col3] = TempPointsSymbol[row2, col3]; // } // //最后一个子数组的index仅仅有一个。 基数排序using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Merge { public class RadixSorter { //基数排序 public int[] RadixSort(int[] ArrayToSort, int digit) { //low to high digit for (int k = 1; k <= digit; k++) { //temp array to store the sort result inside digit int[] tmpArray = new int[ArrayToSort.Length]; //temp array for countingsort int[] tmpCountingSortArray = new int[10] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; //CountingSort for (int i = 0; i < ArrayToSort.Length; i++) { //split the specified digit from the element int tmpSplitDigit = ArrayToSort[i] / (int)Math.Pow(10, k - 1) - (ArrayToSort[i] / (int)Math.Pow(10, k)) * 10; tmpCountingSortArray[tmpSplitDigit] += 1; } for (int m = 1; m < 10; m++) { tmpCountingSortArray[m] += tmpCountingSortArray[m - 1]; } //output the value to result for (int n = ArrayToSort.Length - 1; n >= 0; n--) { int tmpSplitDigit = ArrayToSort[n] / (int)Math.Pow(10, k - 1) - (ArrayToSort[n] / (int)Math.Pow(10, k)) * 10; tmpArray[tmpCountingSortArray[tmpSplitDigit] - 1] = ArrayToSort [n]; tmpCountingSortArray[tmpSplitDigit] -= 1; } //copy the digit-inside sort result to source array for (int p = 0; p < ArrayToSort.Length; p++) { ArrayToSort[p] = tmpArray[p]; } } return ArrayToSort; } } class Program { static void Main(string[] args) { int[] intArray = new int[] { 5, 3, 7, 4, 8, 2, 9, 1, 0, 6 }; int[] newIntArray = intArray; RadixSorter rS=new RadixSorter(); newIntArray = rS.RadixSort(intArray, intArray.Length); foreach (int i in intArray) { Console.Write(i + " "); } Console.ReadKey(); } } } 计数排序using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Merge { class Program { /// <summary> /// 计数排序。 堆排序using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Merge { class Program { //堆排序算法(传递待排数组名,即:数组的地址。故形參数组的各种操作反应到实參数组上) private static void HeapSortFunction(int[] array) { try { BuildMaxHeap(array); //创建大顶推(初始状态看做:总体无序) for (int i = array.Length - 1; i > 0; i--) { Swap(ref array[0], ref array[i]); //将堆顶元素依次与无序区的最后一位交换(使堆顶元素进入有序区) MaxHeapify(array, 0, i); //又一次将无序区调整为大顶堆 } } catch (Exception ex) { Console.Write(ex.Message); } } ///<summary> /// 创建大顶推(根节点大于左右子节点) ///</summary> ///<param name="array">待排数组</param> private static void BuildMaxHeap(int[] array) { try { //依据大顶堆的性质可知:数组的前半段的元素为根节点,其余元素都为叶节点 for (int i = array.Length / 2 - 1; i >= 0; i--) //从最底层的最后一个根节点開始进行大顶推的调整 { MaxHeapify(array, i, array.Length); //调整大顶堆 } } catch (Exception ex) { Console.Write(ex.Message); } } ///<summary> /// 大顶推的调整过程 ///</summary> ///<param name="array">待调整的数组</param> ///<param name="currentIndex">待调整元素在数组中的位置(即:根节点)</param> ///<param name="heapSize">堆中全部元素的个数</param> private static void MaxHeapify(int[] array, int currentIndex, int heapSize) { try { int left = 2 * currentIndex + 1; //左子节点在数组中的位置 int right = 2 * currentIndex + 2; //右子节点在数组中的位置 int large = currentIndex; //记录此根节点、左子节点、右子节点 三者中最大值的位置 if (left < heapSize && array[left] > array[large]) //与左子节点进行比較 { large = left; } if (right < heapSize && array[right] > array[large]) //与右子节点进行比較 { large = right; } if (currentIndex != large) //假设 currentIndex != large 则表明 large 发生变化(即:左右子节点中有大于根节点的情况) { Swap(ref array[currentIndex], ref array[large]); //将左右节点中的大者与根节点进行交换(即:实现局部大顶堆) MaxHeapify(array, large, heapSize); //以上次调整动作的large位置(为此次调整的根节点位置),进行递归调整 } } catch (Exception ex) { Console.Write(ex.Message); } } ///<summary> /// 交换函数 ///</summary> ///<param name="a">元素a</param> ///<param name="b">元素b</param> private static void Swap(ref int a, ref int b) { int temp = 0; temp = a; a = b; b = temp; } static void Main(string[] args) { int[] intArray = new int[] { 5, 3, 7, 4, 8, 2, 9, 1, 0, 6 }; HeapSortFunction(intArray); foreach (int i in intArray) { Console.Write(i + " "); } Console.ReadKey(); } } } 排序的分类/稳定性/时间复杂度和空间复杂度总结版权声明:本文博客原创文章。博客,未经同意,不得转载。 |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论