简体   繁体   English

C#中的通用Mergesort

[英]Generic Mergesort in C#

I am trying to implement a generic Mergesort algorithm in C# , but I am having difficulty with the Constraints . 我试图在C#实现一个通用的Mergesort算法,但是我对Constraints有困难。 I have searched many references but I can't find any that are implementing the algorithm like I am. 我搜索了很多参考文献,但我找不到像我这样实现算法的任何参考文献。

MergeSort algorithm in C# C#中的MergeSort算法

Generic Implementation of Sorting Algorithms 排序算法的一般实现

Anyways, I am trying to provide an implementation that only allows the user to Mergesort a dataset that inherits from the IComparable interface. 无论如何,我试图提供一种实现,只允许用户Mergesort一个继承自IComparable接口的数据集。

Below is what I have so far: 以下是我到目前为止:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SortUtil
{
    class Program
    {
        static void Main(string[] args)
        {
            List<int> testList = new List<int> { 1, 5, 2, 7, 3, 9, 4, 6 };
            Mergesort.mergeSort<int>(testList); // Compiler Error at this Line.
        }
    }
    class Mergesort
    {   
        public static void mergeSort<T>(ref List<T> inputData)
            where T: IComparable<T>
        {
            mergeSort(ref inputData, 0, inputData.Count - 1);
        }

        private static void mergeSort<T>(ref List<T> inputData, int firstIndex, int lastIndex)
            where T: IComparable<T>
        {
            // If the firstIndex is greater than the lastIndex then the recursion 
            // has divided the problem into a single item. Return back up the call 
            // stack.
            if (firstIndex >= lastIndex)
                return;

            int midIndex = (firstIndex + lastIndex) / 2;

            // Recursively divide the first and second halves of the inputData into
            // its two seperate parts.
            mergeSort(ref inputData, firstIndex, midIndex);
            mergeSort(ref inputData, midIndex + 1, lastIndex);

            // Merge the two remaining halves after dividing them in half.
            merge(ref inputData, firstIndex, midIndex, lastIndex);
        }

        private static void merge<T>(ref List<T> inputData, int firstIndex, int midIndex, int lastIndex)
            where T: IComparable<T>
        {
            int currentLeft = firstIndex;
            int currentRight = midIndex + 1;

            T[] tempData = new T[(lastIndex - firstIndex) + 1];
            int tempPos = 0;

            // Check the items at the left most index of the two havles and compare
            // them. Add the items in ascending order into the tempData array.
            while (currentLeft <= midIndex && currentRight <= lastIndex)
                if (inputData.ElementAt(currentLeft).CompareTo(inputData.ElementAt(currentRight)) < 0)
                {
                    tempData[tempPos++] = inputData.ElementAt(currentLeft++);
                }
                else
                {
                    tempData[tempPos++] = inputData.ElementAt(currentRight++);
                }

            // If there are any remaining items to be added to the tempData array,
            // add them.

            while (currentLeft <= midIndex)
            {
                tempData[tempPos++] = inputData.ElementAt(currentLeft++);
            }

            while (currentRight <= lastIndex)
            {
                tempData[tempPos++] = inputData.ElementAt(currentRight++);
            }

            // Now that the items have been sorted, copy them back into the inputData
            // reference that was passed to this function.
            tempPos = 0;
            for (int i = firstIndex; i <= lastIndex; i++) {
                inputData.Insert(firstIndex, tempData.ElementAt(tempPos));
            }
        }
    }
}

My issue: I am getting a Compiler error in the Main method of the Program class; My issue:我在Program类的Main方法中遇到Compiler错误; however, shouldn't I have to supply the mergeSort function the parametrized type when I call it statically? 但是,当我静态调用它时,我不应该提供参数化类型的mergeSort函数吗?

I am getting the error "The best overloaded method match for... has some invalid arguments." 我收到错误"The best overloaded method match for... has some invalid arguments."

I would greatly appreciate any implementation suggestions and/or any way of correcting this error. 我将非常感谢任何实现建议和/或任何纠正此错误的方法。 Note, I am most comfortable in Java, and since C# doesn't directly support wildcards this approach is foreign to me. 注意,我最熟悉Java,而且由于C#不直接支持通配符,这种方法对我来说很陌生。 Any explanations on this would be appreciated as well. 对此的任何解释也将受到赞赏。

MergeSort reuires a ref parameter, so it needs the ref keyword. MergeSort reuires一个ref参数,所以它需要的ref关键字。 This should work: 这应该工作:

Mergesort.mergeSort<int>(ref testList);  

The ref keyword causes an argument to be passed by reference, not by value. ref关键字导致参数通过引用传递,而不是通过值传递。 The effect of passing by reference is that any change to the parameter in the method is reflected in the underlying argument variable in the calling method. 通过引用传递的效果是方法中对参数的任何更改都会反映在调用方法中的基础参数变量中。 The value of a reference parameter is always the same as the value of the underlying argument variable. 引用参数的值始终与基础参数变量的值相同。

You could remove ref from all of your parameters since you do not seem to be using its functionality. 您可以从所有参数中删除ref ,因为您似乎没有使用其功能。

Also you would not need to provide generic parameter type in most cases because the compiler will infer the type for you. 在大多数情况下,您也不需要提供通用参数类型,因为编译器会为您推断类型。 So this should work (assuming you've removed ref from the parameters) in most cases: 所以这应该有效(假设你已经从参数中删除了ref )在大多数情况下:

Mergesort.mergeSort(testList);

Also List<T> and arrays have indexers so you can get at specific elements via inputData[index] instead of ElementAt . List<T>和数组也有索引器,因此您可以通过inputData[index]而不是ElementAt获取特定元素。 It's just less typing that way. 这种方式只是少打字。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM