C# c语言中的合并排序算法#

C# c语言中的合并排序算法#,c#,algorithm,console,mergesort,C#,Algorithm,Console,Mergesort,我为合并类编写了以下代码: class Merge { public static void sort(IComparable[] a) { sort(a, 0, a.Length); } public static void sort(IComparable[] a, int low, int high) { int N = high - low; if (N <= 1)

我为合并类编写了以下代码:

class Merge
{

    public static void sort(IComparable[] a)
    {
        sort(a, 0, a.Length);
    }

    public static void sort(IComparable[] a, int low, int high)
    {
        int N = high - low;
        if (N <= 1)
            return;

        int mid = low + N / 2;

        sort(a, low, mid);
        sort(a, mid, high);

        IComparable[] aux = new IComparable[N];
        int i = low, j = mid;
        for (int k = 0; k < N; k++)
        {
            if (i == mid) aux[k] = a[j++];
            else if (j == high) aux[k] = a[i++];
            else if (a[j].CompareTo(a[i]) < 0) aux[k] = a[j++];
            else aux[k] = a[i++];
        }

        for (int k = 0; k < N; k++)
        {
            a[low + k] = aux[k];
        }
    }

    private static Boolean isSorted(IComparable[] a)
    {
        for (int i = 1; i < a.Length; i++)
            if (a[i].CompareTo(a[i - 1]) < 0) return false;
        return true;
    }

}
类合并
{
公共静态无效排序(IComparable[]a)
{
排序(a,0,a.长度);
}
公共静态无效排序(IComparable[]a,int-low,int-high)
{
int N=高-低;

如果(N您的
sort
方法是静态的,您不应该从类的实例调用它

你应该这样称呼它:

Merge.sort(MyArray);
不是:


事实上,由于您的
Merge
类没有实例方法,因此创建它的实例没有意义,您可能只需要将整个类标记为静态。

此代码有两个问题:

  • 签名不匹配,
    IComparable[]
    在本例中与
    double[]
    不直接兼容
  • 不能通过实例直接调用
    sort
    方法
  • 修复此问题所需的最小更改量是使该方法通用,并调用
    Merge.sort
    ,而不是
    ms.sort

    下面是我将如何实现排序的方法:

    public static void sort<T>(T[] a)
        where T : IComparable<T>
    {
        sort(a, 0, a.Length);
    }
    
    public static void sort<T>(T[] a, int low, int high)
        where T : IComparable<T>
    {
        int N = high - low;
        if (N <= 1)
            return;
    
        int mid = low + N / 2;
    
        sort(a, low, mid);
        sort(a, mid, high);
    
        T[] aux = new T[N];
        int i = low, j = mid;
        for (int k = 0; k < N; k++)
        {
            if (i == mid) aux[k] = a[j++];
            else if (j == high) aux[k] = a[i++];
            else if (a[j].CompareTo(a[i]) < 0) aux[k] = a[j++];
            else aux[k] = a[i++];
        }
    
        for (int k = 0; k < N; k++)
        {
            a[low + k] = aux[k];
        }
    }
    
    为此:

    Merge.sort(...);
    
    //合并排序递归
    公共void合并排序(int[]输入,int startIndex,int endIndex)
    {
    int mid;
    如果(endIndex>startIndex)
    {
    mid=(endIndex+startIndex)/2;
    合并排序(输入、起始索引、mid);
    合并排序(输入,(中间+1),结束索引);
    合并(输入,开始索引,(中间+1),结束索引);
    }
    }
    公共无效合并(int[]输入,int左,int中,int右)
    {
    //合并过程需要θ(n)时间
    int[]temp=new int[input.Length];
    int i、左端、长THOFINPUT、tmpPos;
    左端=中间-1;
    tmpPos=左;
    lengthOfInput=右-左+1;
    //从左排序数组或右排序数组中选择较小的元素并将它们放置在临时数组中。
    while((左
    公共静态int[]合并排序(int[]ar)
    {
    Func firstHalf=(数组)=>
    {
    返回array.Take((array.Length+1)/2.ToArray();
    };
    Func secondHalf=(数组)=>
    {
    返回array.Skip((array.Length+1)/2.ToArray();
    };
    Func mergestoredarray=(ar1,ar2)=>
    {
    int[]mergedArray=newint[ar1.Length+ar2.Length];
    int i1=0,i2=0,currentMin;
    而(i1
    一个简单的C代码来进行合并排序

    using System;
    
    namespace MergeSort
    {
        class Program
        {
            static void Main(string[] args)
            {            
                int[] arInt = { 6, 4, 2, 8, 4, 8, 11, 1, 7, 4, 13, 5, 45, -1, 0, -7, 56, 10, 57 };
                var sortedIntAr = GenericMergeSort<int>.Sort(arInt);
    
                string[] arStr = { "Here", "Is", "A", "Cat", "Really", "Fast", "And", "Clever" };
                var sortedStrAr = GenericMergeSort<string>.Sort(arStr);
    
                Console.WriteLine(String.Join(',', sortedIntAr));
                Console.WriteLine(String.Join(',', sortedStrAr));
    
                Console.ReadLine();
            }
    
        }
        class GenericMergeSort<T> where T : IComparable
        {
            public static T[] Sort(T[] ar)
            {
                var arLen = ar.Length;
                if (arLen < 2)
                    return ar;
    
                var arL = ar.AsSpan(0..(arLen / 2)).ToArray();
                var arR = ar.AsSpan((arLen / 2)..arLen).ToArray();
    
                arL = Sort(arL);
                arR = Sort(arR);
    
                return Merge(arL, arR);
            }
    
            private static T[] Merge(T[] arL, T[] arR)
            {
                var mergedArray = new T[arL.Length + arR.Length];
                int iM = 0, iL = 0, iR = 0;
    
                while (iL < arL.Length || iR < arR.Length)
                {
                    mergedArray[iM++] = iL < arL.Length && (iR > arR.Length - 1 || arL[iL].CompareTo(arR[iR]) < 0)
                                        ? arL[iL++] : arR[iR++];
                }
                return mergedArray;
            }
        }
    }
    
    使用系统;
    名称空间合并排序
    {
    班级计划
    {
    静态void Main(字符串[]参数)
    {            
    int[]arInt={6,4,2,8,4,8,11,1,7,4,13,5,45,-1,0,-7,56,10,57};
    var sortedIntAr=GenericMergeSort.Sort(arInt);
    string[]arStr={“这里”、“是”、“A”、“猫”、“真的”、“快”、“和”、“聪明”};
    var sortedStrAr=GenericMergeSort.Sort(arStr);
    Console.WriteLine(String.Join(',,sortedIntAr));
    Console.WriteLine(String.Join(',,sortedStrAr));
    Console.ReadLine();
    }
    }
    类GenericMergeSort,其中T:IComparable
    {
    公共静态T[]排序(T[]ar)
    {
    var arLen=ar.长度;
    如果(阿伦<2)
    返回ar;
    var arL=ar.AsSpan(0..(arLen/2)).ToArray();
    var arR=ar.AsSpan((arLen/2)…arLen.ToArray();
    arL=排序(arL);
    arR=排序(arR);
    返回合并(arL、arR);
    }
    专用静态T[]合并(T[]arL,T[]arR)
    {
    var mergedArray=新T[arL.Length+arR.Length];
    int iM=0,iL=0,iR=0;
    而(iLarR.Length-1 | | arL[iL]。比较(arR[iR])<0)
    ?arL[iL++]:arR[iR++];
    }
    返回Darray;
    }
    }
    }
    
    这是输出

    -7,-1,0,1,2,4,4,5,6,7,8,8,10,11,13,45,56,57

    A、 而且,猫,聪明,快速,在这里,实际上是一种简单的C#merge排序

    using System.Collections.Generic;
    
    namespace Sort
    {
        public class MergeSort
        {
            public static List<int> mergeSort(List<int> list)
            {
                if (list.Count <= 1) return list;
    
                List<int> result;
                List<int> left = new List<int>();
                List<int> right = new List<int>();
    
                int midPoint = list.Count / 2;
    
                left.AddRange(list.GetRange(0, midPoint));
                right.AddRange(list.GetRange(midPoint, list.Count - midPoint));
    
                left = mergeSort(left);
    
                right = mergeSort(right);
    
                result = merge(left, right);
                return result;
            }
    
            //This method will be responsible for combining our two sorted arrays into one giant array
            public static List<int> merge(List<int> left, List<int> right)
            {
                List<int> result = new List<int>();
    
                int indexLeft = 0, indexRight = 0, indexResult = 0;
                while (indexLeft < left.Count || indexRight < right.Count)
                {
                    //if both arrays have elements  
                    if (indexLeft < left.Count && indexRight < right.Count)
                    {
                        if (left[indexLeft] <= right[indexRight])
                        {
                            result.Add(left[indexLeft]);
                            indexLeft++;
                        }
                        else
                        {
                            result.Add(right[indexRight]);
                            indexRight++;
                        }
                    }
                    else if (indexLeft < left.Count)
                    {
                        result.Add(left[indexLeft]);
                        indexLeft++;
                    }
                    else if (indexRight < right.Count)
                    {
                        result.Add(right[indexRight]);
                        indexRight++;
                    }
                    indexResult++;
                }
                return result;
            }
        }
    }
    
    使用System.Collections.Generic;
    名称空间排序
    {
    公共类合并排序
    {
    公共静态列表合并排序(列表列表)
    {
    
    如果(list.Count)尝试调用MyArray.sort();没关系-我以为这是一个扩展方法…如果您适当地更改签名-添加“this”关键字,您可以扩展数组对象。我有两个错误。第一:
    Error 1“MergeSort.Merge.sort(System.IComparable[])的最佳重载方法匹配'具有一些无效参数c:\users\hamed\documents\visual studio 2010\Projects\MergeSort\MergeSort\Program.cs 22 9 MergeSort
    和第二个是
    错误2参数1:无法从'double[]转换为'System.IComparable[]'c:\users\hamed\documents\visualstudio 2010\Projects\MergeSort\MergeSort\Program.cs 22 17 MergeSort
    @HamedKamrava:请参阅@LasseVKarlsen的答案。您还有另一个问题,
    double[]
    无法自动转换为<
    Merge.sort(...);
    
        //merge sort recurcive
    
        public void MergeSort(int[] input,int startIndex,int endIndex)
        {
            int mid;
    
            if (endIndex > startIndex)
            {
                mid = (endIndex + startIndex) / 2;
                MergeSort(input, startIndex, mid);
                MergeSort(input, (mid + 1), endIndex);
                Merge(input, startIndex, (mid + 1), endIndex);
            }
        }
    
        public void Merge(int[] input, int left, int mid, int right)
        {
            //Merge procedure takes theta(n) time
            int[] temp = new int[input.Length];
            int i, leftEnd,lengthOfInput,tmpPos;
            leftEnd = mid - 1;
            tmpPos = left;
            lengthOfInput = right - left + 1;
    
            //selecting smaller element from left sorted array or right sorted array and placing them in temp array.
            while ((left <= leftEnd) && (mid <= right))
            {
                if (input[left] <= input[mid])
                {
                    temp[tmpPos++] = input[left++];
                }
                else
                { 
                    temp[tmpPos++]=input[mid++];
                }
            }
            //placing remaining element in temp from left sorted array
            while (left <= leftEnd)
            {
                temp[tmpPos++] = input[left++];
            }
    
            //placing remaining element in temp from right sorted array
            while (mid <= right)
            {
                temp[tmpPos++] = input[mid++];
            }
    
            //placing temp array to input
            for (i = 0; i < lengthOfInput;i++ )
            {
                input[right]=temp[right];
                right--;
            }
        }
    
         int[] input3 = { 22, 4, 6, 0, 9, 12, 156, 86,99};
         MergeSort(input3, 0, input3.Length - 1);
            for (int i = 0; i < input3.Length; i++)
                Console.Write(input3[i]+", ");
            Console.WriteLine("");
    
    public static int[] mergeSort(int[] ar)
    {
        Func<int[], int[]> firstHalf = (array) =>
         {
             return array.Take((array.Length + 1) / 2).ToArray();
         };
    
        Func<int[], int[]> secondHalf = (array) =>
        {
            return array.Skip((array.Length + 1) / 2).ToArray();                
        };
    
        Func<int[], int[], int[]> mergeSortedArrays = (ar1, ar2) =>
        {
            int[] mergedArray = new int[ar1.Length + ar2.Length];
    
            int i1 = 0, i2 = 0, currentMin;
    
            while (i1 < ar1.Length || i2 < ar2.Length)
            {
                if (i1 < ar1.Length && i2 < ar2.Length)
                {
                    if (ar1[i1] < ar2[i2])
                    {
                        currentMin = ar1[i1];
                        i1++;
                    }
                    else
                    {
                        currentMin = ar2[i2];
                        i2++;
                    }
                }
                else if (i1 < ar1.Length)
                {
                    currentMin = ar1[i1];
                    i1++;
                }
                else
                {
                    currentMin = ar2[i2];
                    i2++;
                }
                mergedArray[i1 + i2 - 1] = currentMin;
            }
            return mergedArray;
        };
    
        int[] half1 = firstHalf(ar); //always /geq than half2
        int[] half2 = secondHalf(ar);
    
        if (half1.Length < 2)
            return mergeSortedArrays(half1, half2);
        else
            return mergeSortedArrays(mergeSort(half1), mergeSort(half2));
    
    }
    
    using System;
    
    namespace MergeSort
    {
        class Program
        {
            static void Main(string[] args)
            {            
                int[] arInt = { 6, 4, 2, 8, 4, 8, 11, 1, 7, 4, 13, 5, 45, -1, 0, -7, 56, 10, 57 };
                var sortedIntAr = GenericMergeSort<int>.Sort(arInt);
    
                string[] arStr = { "Here", "Is", "A", "Cat", "Really", "Fast", "And", "Clever" };
                var sortedStrAr = GenericMergeSort<string>.Sort(arStr);
    
                Console.WriteLine(String.Join(',', sortedIntAr));
                Console.WriteLine(String.Join(',', sortedStrAr));
    
                Console.ReadLine();
            }
    
        }
        class GenericMergeSort<T> where T : IComparable
        {
            public static T[] Sort(T[] ar)
            {
                var arLen = ar.Length;
                if (arLen < 2)
                    return ar;
    
                var arL = ar.AsSpan(0..(arLen / 2)).ToArray();
                var arR = ar.AsSpan((arLen / 2)..arLen).ToArray();
    
                arL = Sort(arL);
                arR = Sort(arR);
    
                return Merge(arL, arR);
            }
    
            private static T[] Merge(T[] arL, T[] arR)
            {
                var mergedArray = new T[arL.Length + arR.Length];
                int iM = 0, iL = 0, iR = 0;
    
                while (iL < arL.Length || iR < arR.Length)
                {
                    mergedArray[iM++] = iL < arL.Length && (iR > arR.Length - 1 || arL[iL].CompareTo(arR[iR]) < 0)
                                        ? arL[iL++] : arR[iR++];
                }
                return mergedArray;
            }
        }
    }
    
    using System.Collections.Generic;
    
    namespace Sort
    {
        public class MergeSort
        {
            public static List<int> mergeSort(List<int> list)
            {
                if (list.Count <= 1) return list;
    
                List<int> result;
                List<int> left = new List<int>();
                List<int> right = new List<int>();
    
                int midPoint = list.Count / 2;
    
                left.AddRange(list.GetRange(0, midPoint));
                right.AddRange(list.GetRange(midPoint, list.Count - midPoint));
    
                left = mergeSort(left);
    
                right = mergeSort(right);
    
                result = merge(left, right);
                return result;
            }
    
            //This method will be responsible for combining our two sorted arrays into one giant array
            public static List<int> merge(List<int> left, List<int> right)
            {
                List<int> result = new List<int>();
    
                int indexLeft = 0, indexRight = 0, indexResult = 0;
                while (indexLeft < left.Count || indexRight < right.Count)
                {
                    //if both arrays have elements  
                    if (indexLeft < left.Count && indexRight < right.Count)
                    {
                        if (left[indexLeft] <= right[indexRight])
                        {
                            result.Add(left[indexLeft]);
                            indexLeft++;
                        }
                        else
                        {
                            result.Add(right[indexRight]);
                            indexRight++;
                        }
                    }
                    else if (indexLeft < left.Count)
                    {
                        result.Add(left[indexLeft]);
                        indexLeft++;
                    }
                    else if (indexRight < right.Count)
                    {
                        result.Add(right[indexRight]);
                        indexRight++;
                    }
                    indexResult++;
                }
                return result;
            }
        }
    }