C# 为什么在这个实现中插入排序总是优于合并排序?

C# 为什么在这个实现中插入排序总是优于合并排序?,c#,algorithm,mergesort,insertion-sort,C#,Algorithm,Mergesort,Insertion Sort,我不明白:对于任何大小的n,为什么我的插入排序实现每次都优于合并排序 public List<Int32> InsertionSort(List<Int32> elements, Boolean ascending = true) { for (Int32 j = 1; j < elements.Count; j++) { Int32 key = elements[j];

我不明白:对于任何大小的
n
,为什么我的插入排序实现每次都优于合并排序

    public List<Int32> InsertionSort(List<Int32> elements, Boolean ascending = true)
    {
        for (Int32 j = 1; j < elements.Count; j++)
        {
            Int32 key = elements[j];
            Int32 i = j - 1;

            while (i >= 0 && (elements[i].CompareTo(key) > 0) == ascending)
                elements[i + 1] = elements[i--];

            elements[i + 1] = key;
        }

        return elements;
    }

以及测试代码:

    static void Main(string[] args)
    {
        for (int i = 1; i < 100000; i*=10)
        {
            List<Int32> elements = GetFilledList(i, 0, Int32.MaxValue, false);
            Console.WriteLine("SORTING {0} ELEMENTS", elements.Count);

            Stopwatch sw = new Stopwatch();

            //MERGE SORT
            sw.Start();
            new MergeSort().Sort(elements);
            sw.Stop();
            Console.WriteLine("MERGE-SORT: TIME SPENT: {0}ms ({1} ticks)", sw.ElapsedMilliseconds, sw.ElapsedTicks);

            //INSERTION SORT
            sw.Restart();
            new InsertionSort().Sort(elements);
            sw.Stop();
            Console.WriteLine("INSERTION-SORT: TIME SPENT: {0}ms ({1} ticks)", sw.ElapsedMilliseconds, sw.ElapsedTicks);
            Console.WriteLine();   
        }

        Console.ReadKey();
    }
static void Main(字符串[]args)
{
对于(int i=1;i<100000;i*=10)
{
列表元素=GetFilled列表(i,0,Int32.MaxValue,false);
WriteLine(“排序{0}元素”,ELEMENTS.Count);
秒表sw=新秒表();
//合并排序
sw.Start();
新建MergeSort().Sort(元素);
sw.Stop();
WriteLine(“MERGE-SORT:花费的时间:{0}ms({1}个刻度)”,sw.elapsedmillesons,sw.ElapsedTicks);
//插入排序
sw.Restart();
新建InsertionSort().Sort(元素);
sw.Stop();
WriteLine(“插入排序:所用时间:{0}ms({1}个刻度)”,sw.elapsedmillesons,sw.ElapsedTicks);
Console.WriteLine();
}
Console.ReadKey();
}
如果有人想知道我是从哪里得到这些算法的

编辑:

static List getFilled列表(Int32数量、Int32下界、Int32上界、布尔mayreat=true)
{
列表编号=新列表();
随机r=新随机();
对于(int i=0;i
对10000个元素进行排序几乎不足以有效评估一个算法。再大一点

还有,输入是随机的吗?发布您的
getFilled列表的实现

在执行插入排序之前,您需要取消对
元素的排序(或只是重新初始化
元素


如果你改变排序的顺序,会发生什么?我猜您正在做mergesort中的所有工作,然后插入排序只是对已经排序的列表进行排序,它实际上非常擅长(O(n),假设一个正常的实现)。

因为在合并排序之后,元素中的对象已经排序。再做一次

elements = GetFilledList(i, 0, Int32.MaxValue, false);

sw.Restart();

对于小输入,插入排序应比合并排序快;这就是O(N)的工作原理

f(n)=O(g(n))如果对于所有n,大于n0,f(n)
像具有良好复杂性的算法通常具有较高的C值,因此在获得较大的输入之前,它们不会真正击败“较慢”的算法

虽然esskar似乎已经发现了您面临的主要问题,但请记住,在未来,您可能需要使用更多、更大的输入测试算法,才能真正看到更好的算法

    static List<Int32> GetFilledList(Int32 quantity, Int32 lowerBound, Int32 upperBound, Boolean mayRepeat = true)
    {
        List<Int32> numbers = new List<Int32>();

        Random r = new Random();
        for (int i = 0; i < quantity; i++)
        {
            Int32 numero = r.Next(lowerBound, upperBound); 

            while(!mayRepeat && numbers.Contains(numero))
                numero = r.Next(lowerBound, upperBound);

            numbers.Add(numero);
        }

        return numbers;
    }
elements = GetFilledList(i, 0, Int32.MaxValue, false);
sw.Restart();
f(n) = O(g(n)) if for all n, greater than n0, f(n) < C * g(n)