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)