using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Sort { class MergeSorter { /// <summary> /// 兼并排序之归:兼并排序进口 /// </summary> /// <param name="data">无序数组</param> /// <returns>有序数组</returns> public static int[] Sort(int[] data) { //若data为null,或只剩下1 or 0个元素,返回,不排序 if (null == data || data.Length <= 1) { return data; } //取数组中心下标 int middle = data.Length >> 1; //初始化暂时数组let,right,并定义result作为终究有序数组,若数组元素奇数个,将把过剩的那元素空间预留在right暂时数组 int[] left = new int[middle]; int[] right = new int[data.Length - middle]; int[] result = new int[data.Length]; for (int i = 0; i < data.Length; i++) { if (i < middle) { left[i] = data[i]; } else { right[i-middle] = data[i]; //此处i-middle,让我免却定义一个j,机能有所提高 } } left = Sort(left);//递归左数组 right = Sort(right);//递归右数组 result = Merge(left, right);//最先排序 return result; } /// <summary> /// 兼并排序之并:排序在这一步 /// </summary> /// <param name="a">左数组</param> /// <param name="b">右数组</param> /// <returns>兼并摆布数组排序后返回</returns> private static int[] Merge(int[] a, int[] b) { //定义效果数组,用来存储终究效果 int[] result = new int[a.Length + b.Length]; int i = 0, j = 0, k = 0; while (i < a.Length && j < b.Length) { if (a[i] < b[j])//左数组中元素小于右数组中元素 { result[k++] = a[i++];//将小的谁人放到效果数组 } else//左数组中元素大于右数组中元素 { result[k++] = b[j++];//将小的谁人放到效果数组 } } while (i < a.Length)//这里实际上是另有左元素,但没有右元素 { result[k++] = a[i++]; } while (j < b.Length)//有右元素,无左元素 { result[k++] = b[j++]; } return result;//返回效果数组 } } }
兼并排序:
兼并(Merge)排序法是将两个(或两个以上)有序表兼并成一个新的有序表,即把待排序序列分为多少个子序列,每个子序列是有序的。然后再把有序子序列兼并为团体有序序列。该算法是采纳分治法(Divide and Conquer)的一个异常典范的运用。
将已有序的子序列兼并,获得完整有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表兼并成一个有序表,称为2-路兼并。
假定我们有一个没有排好序的序列,那末起首我们运用支解的要领将这个序列支解成一个一个已排好序的子序列,然后再利用兼并的要领将一个个的子序列兼并成排序好的序列。支解和兼并的历程能够看下面的图例。
从上图能够看出,我们起首把一个未排序的序列从中心支解成2部份,再把2部份分红4部份,顺次支解下去,直到支解成一个一个的数据,再把这些数据两两兼并到一同,使之有序,不断的兼并,末了成为一个排好序的序列。
怎样把两个已排序好的子序列兼并成一个排好序的序列呢?能够参看下面的要领。
假定我们有两个已排序好的子序列。
序列A:1 23 34 65
序列B:2 13 14 87
那末能够根据下面的步骤将它们兼并到一个序列中。
(1)起首设定一个新的数列C[8]。
(2)A[0]和B[0]比较,A[0] = 1,B[0] = 2,A[0] < B[0],那末C[0] = 1
(3)A[1]和B[0]比较,A[1] = 23,B[0] = 2,A[1] > B[0],那末C[1] = 2
(4)A[1]和B[1]比较,A[1] = 23,B[1] = 13,A[1] > B[1],那末C[2] = 13
(5)A[1]和B[2]比较,A[1] = 23,B[2] = 14,A[1] > B[2],那末C[3] = 14
(6)A[1]和B[3]比较,A[1] = 23,B[3] = 87,A[1] < B[3],那末C[4] = 23
(7)A[2]和B[3]比较,A[2] = 34,B[3] = 87,A[2] < B[3],那末C[5] = 34
(8)A[3]和B[3]比较,A[3] = 65,B[3] = 87,A[3] < B[3],那末C[6] = 65
(9)末了将B[3]复制到C中,那末C[7] = 87。兼并完成。
C#移位运算(左移和右移)
兼并排序,时候复杂度为O(nlogn)。
兼并排序的效力是比较高的,设数列长为N,将数列分开成小数列一共要logN步,每步都是一个兼并有序数列的历程,时候复杂度能够记为O(N),故一共为O(N*logN)。由于兼并排序每次都是在相邻的数据中举行操纵,所以兼并排序在O(N*logN)的几种排序要领(疾速排序,兼并排序,希尔排序,堆排序)也是效力比较高的。
以上就是 C# 兼并排序的内容,更多相关内容请关注ki4网(www.ki4.cn)!