zoukankan      html  css  js  c++  java
  • C#实现常用排序算法

      本文实现的常用排序算法包括:冒泡排序,快速排序,希尔排序,插入排序,选择排序,归并排序。

      冒泡排序:从后向前遍历数组,比较相邻的两个元素。如果两个元素的顺序是错的,那么就交换这两个元素。如果某次遍历过程中,元素都没有发生交换,那么说明数组已经排序好,可以中止停止排序。最坏的情况是在起始数组中,需要排在最后的元素位于最前边,那么冒泡算法必须经过n-1次遍历才能将数组排列好,而不能提前完成排序。该算法的时间复杂度是O(n^2),是稳定的排序算法。

    BubbleSort
     1         /// <summary>
     2         /// 冒泡排序
     3         /// </summary>
     4         /// <param name="array">待排序的数组</param>
     5         /// <param name="isReverse">是否逆序</param>
     6         /// <param name="sortedArray">排序后的数组</param>
     7         public static void BubbleSort(IEnumerable<T> array, bool isReverse, out List<T> sortedArray)
     8         {
     9             sortedArray = array.ToList();
    10             int n = sortedArray.Count; ;
    11             int sign;//结束标记
    12             for (int j = 0; j < n - 1; j++)
    13             {
    14                 sign = 0;
    15                 for (int i = n - 1; i > j; i--)
    16                 {
    17                     T item = sortedArray[i];
    18                     T preItem = sortedArray[i - 1];
    19                     if (isReverse && item.CompareTo(preItem) > 0 || //逆序
    20                         !isReverse && item.CompareTo(preItem) < 0)  //顺序
    21                     {
    22                         sign = 1;//不能结束
    23                         Swap(sortedArray, i, i-1);//交换元素的位置
    24                     }
    25                 }
    26                 if (sign < 1)
    27                     break;
    28             }
    29         }

      快速排序:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。该算法是对冒泡排序的改进算法,时间复杂度是O(n*logn),不是稳定的排序算法。

    QuickSort
     1         /// <summary>
     2         /// 快速排序
     3         /// </summary>
     4         /// <param name="array">待排序的数组</param>
     5         /// <param name="isReverse">是否逆序</param>
     6         /// <param name="sortedArray">排序后的数组</param>
     7         public static void QuickSort(IEnumerable<T> array, bool isReverse, out List<T> sortedArray)
     8         {
     9             sortedArray = array.ToList();
    10             int n = sortedArray.Count;
    11 
    12             int key = 0;//选取第一个元素为两部分数据的分割项的索引
    13 
    14             //将数组分割成两部分
    15             int i = 0, j = n - 1;
    16             while(i < j)
    17             {
    18                 while (j > i)
    19                 {
    20                     if (isReverse && sortedArray[j].CompareTo(sortedArray[key]) > 0 ||
    21                         !isReverse && sortedArray[j].CompareTo(sortedArray[key]) < 0)
    22                     {
    23                         Swap(sortedArray, j, i);
    24                         key = j;
    25                         break;
    26                     }
    27                     j--;
    28                 }
    29                 while (i < j)
    30                 {
    31                     if (isReverse && sortedArray[i].CompareTo(sortedArray[key]) < 0 ||
    32                         !isReverse && sortedArray[i].CompareTo(sortedArray[key]) > 0)
    33                     {
    34                         Swap(sortedArray, j, i);
    35                         key = i;                        
    36                         break;
    37                     }
    38                     i++;
    39                 }
    40             }   
    41             if (n <= 2) return;//结束条件
    42             else
    43             {
    44                 //递归调用,对key前面的数组进行排序
    45                 List<T> array1 = new List<T>();
    46                 for (i = 0; i < key; i++)
    47                 {
    48                     array1.Add(sortedArray[i]);
    49                 }
    50                 QuickSort(array1, isReverse, out array1);
    51                 for (i = 0; i < key; i++)
    52                 {
    53                     sortedArray[i] = array1[i];
    54                 }
    55                 //递归调用,对key后面的数组进行排序
    56                 List<T> array2 = new List<T>();
    57                 for (i = 0; i < n - key - 1; i++)
    58                 {
    59                     array2.Add(sortedArray[key + 1 + i]);
    60                 }
    61                 QuickSort(array2, isReverse, out array2);
    62                 for (i = 0; i < array2.Count; i++)
    63                 {
    64                     sortedArray[key + 1 + i] = array2[i];
    65                 }
    66             }
    67         }

      希尔排序:将要排序的一组数按某个增量d分成若干组,每组中记录的下标相差d。对每组中全部元素进行排序,然后再用一个较小的增量对它进行,在每组中再进行排序。当增量减到1时,整个要排序的数被分成一组,排序完成。该算法是对冒泡排序的改进,又称缩小增量排序,也可配合其他排序算法使用。该算法的时间复杂度是O(n*logn),是不稳定的排序算法。

    ShellSort
     1         /// <summary>
     2         /// 希尔排序
     3         /// </summary>
     4         /// <param name="array">待排序的数组</param>
     5         /// <param name="isReverse">是否逆序</param>
     6         /// <param name="sortedArray">排序后的数组</param>
     7         public static void ShellSort(IEnumerable<T> array, bool isReverse, out List<T> sortedArray)
     8         {
     9             sortedArray = array.ToList();
    10             int n = sortedArray.Count;
    11             //初始化增量
    12             int step = 1;
    13             while (step < n) step = 3 * step + 1;
    14 
    15             while (step > 1)
    16             {
    17                 step = step / 3 + 1;
    18                 for (int i = 0; i < step; i++)
    19                 {
    20                     int nsub = (n - i - 1) / step + 1;
    21                     List<T> subArray = new List<T>();
    22                     for (int j = 0; j < nsub; j++)
    23                     {
    24                         subArray.Add(sortedArray[i + j * step]);
    25                     }
    26                     BubbleSort(subArray, isReverse, out subArray);//此处也可使用其他排序算法
    27                     for (int j = 0; j < nsub; j++)
    28                     {
    29                         sortedArray[i + j * step] = subArray[j];
    30                     }
    31                 }
    32             }
    33         }

      插入排序:假定这个数组的序是排好的,然后从头往后,如果有数比当前外层元素的值大,则将这个数的位置往后挪,直到当前外层元素的值大于或等于它前面的位置为止。算法适用于少量数据的排序,时间复杂度为O(n^2),是稳定的排序方法。

    InsertSort
     1         /// <summary>
     2         /// 插入排序
     3         /// </summary>
     4         /// <param name="array">待排序的数组</param>
     5         /// <param name="isReverse">是否逆序</param>
     6         /// <param name="sortedArray">排序后的数组</param>
     7         public static void InsertSort(IEnumerable<T> array, bool isReverse, out List<T> sortedArray)
     8         {
     9             sortedArray = array.ToList();
    10             int n = sortedArray.Count;
    11             for (int j = 1; j < n; j++)
    12             {
    13                 int i = j - 1;
    14                 T item = sortedArray[i];
    15                 T nextItem = sortedArray[i + 1];
    16                 while (isReverse && item.CompareTo(nextItem) < 0 ||
    17                       !isReverse && item.CompareTo(nextItem) > 0)
    18                 {
    19                     Swap(sortedArray, i, i + 1);//交换元素的位置
    20                     i--;
    21                     if (i >= 0)
    22                     {
    23                         item = sortedArray[i];
    24                         nextItem = sortedArray[i + 1];
    25                     }
    26                     else
    27                     {
    28                         break;
    29                     }
    30                 }               
    31             }
    32         }

      选择排序:先找到起始数组中最小的元素,将它交换到i=0;然后寻找剩下元素中最小的元素,将它交换到i=1的位置…… 直到找到第二大的元素,将它交换到n-2的位置。这时,整个数组的排序完成。该算法的时间复杂度是O(n^2),不是稳定的排序算法。  

    SelectSort
     1         /// <summary>
     2         /// 选择排序
     3         /// </summary>
     4         /// <param name="array">待排序的数组</param>
     5         /// <param name="isReverse">是否逆序</param>
     6         /// <param name="sortedArray">排序后的数组</param>
     7         public static void SelectSort(IEnumerable<T> array, bool isReverse, out List<T> sortedArray)
     8         {
     9             sortedArray = array.ToList();
    10             int n = sortedArray.Count;
    11             int selectIndex;
    12             for (int j = 0; j < n - 1; j++)
    13             {
    14                 selectIndex = j;
    15                 for (int i = j + 1; i < n; i++)
    16                 { 
    17                     T item = sortedArray[i];
    18                     if ((isReverse && sortedArray[selectIndex].CompareTo(item) < 0) ||
    19                         (!isReverse && sortedArray[selectIndex].CompareTo(item) > 0))
    20                     {
    21                         selectIndex = i;
    22                     }
    23                 }
    24                 Swap(sortedArray, selectIndex, j);
    25             }
    26         }

      归并排序:将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。该算法的时间复杂度是O(n*logn),是稳定的排序算法。 

    MergeSort
     1         /// <summary>
     2         /// 归并排序
     3         /// </summary>
     4         /// <param name="array">待排序的数组</param>
     5         /// <param name="isReverse">是否逆序</param>
     6         /// <param name="sortedArray">排序后的数组</param>
     7         public static void MergeSort(IEnumerable<T> array, bool isReverse, out List<T> sortedArray)
     8         {
     9             sortedArray = array.ToList();
    10             int n = sortedArray.Count;
    11 
    12             if (n <= 1) return;//结束标识
    13             
    14             //将数组分为两个数组
    15             int n1 = n / 2;
    16             List<T> array1 = new List<T>();
    17             for (int k = 0; k < n1; k++)
    18             {
    19                 array1.Add(sortedArray[k]);
    20             }
    21             int n2 = n - n1;
    22             List<T> array2 = new List<T>();
    23             for (int k = 0; k < n2; k++)
    24             {
    25                 array2.Add(sortedArray[n1 + k]);
    26             }
    27 
    28             //递归调用
    29             MergeSort(array1, isReverse, out array1);
    30             MergeSort(array2, isReverse, out array2);
    31 
    32             //合并有序序列
    33             int i = 0, j = 0;//array1和array2的索引
    34             int index = 0;//sortedArray的索引
    35             while (i < n1 && j < n2)
    36             {                
    37                 if (isReverse && array1[i].CompareTo(array2[j]) > 0 ||
    38                     !isReverse && array1[i].CompareTo(array2[j]) <= 0)
    39                 {
    40                     sortedArray[index++] = array1[i++];
    41                 }
    42                 else
    43                 {
    44                     sortedArray[index++] = array2[j++];
    45                 }                
    46             }
    47             while (i < n1)
    48             {
    49                 sortedArray[index++] = array1[i++];
    50             }
    51             while (j < n2)
    52             {
    53                 sortedArray[index++] = array2[j++];
    54             }
    55         }
  • 相关阅读:
    The formatter threw an exception while trying to deserialize the message in WCF
    通过Web Deploy方式部署WCF
    The Managed Metadata Service or Connection is currently not available
    How to create Managed Metadata Column
    冒泡算法
    asp.net core 实战项目(一)——ef core的使用
    Vue学习笔记入门篇——安装及常用指令介绍
    Vue学习笔记入门篇——数据及DOM
    Vue学习笔记目录
    Chart.js在Laravel项目中的应用
  • 原文地址:https://www.cnblogs.com/hibernation/p/2961036.html
Copyright © 2011-2022 走看看