所以我使用的是一个使用插入排序,选择排序和合并排序的程序。我计算所有的程序,并制作一个最快的表。我理解为什么合并排序比选择排序和插入排序更有效(b / c比较元素的有效性)。
我的问题是为什么比较数组的元素相对消耗,为什么它使插入和选择排序效率降低。
注意:我是java新手,无法找到有关此主题的任何内容。谢谢您的回复。
答案 0 :(得分:1)
我的问题是为什么比较相对消耗的数组的2个元素....
相对于什么?
实际上,比较某个类的两个实例所花费的时间取决于compareTo
或compare
方法的实现方式。然而,由于计算的性质,比较通常很昂贵。
例如,如果必须比较两个相等(但不同的对象)的字符串,则必须将一个字符串中的每个字符与另一个字符串中的相应字符进行比较。对于长度为M的字符串,即M个字符比较加上循环字符的开销。 (显然,比较在其他情况下更便宜......取决于字符串的不同程度,例如。)
为什么它会使插入和选择排序效率降低。
插入和选择排序较慢(对于大型数据集)的原因是因为它们比其他更复杂的算法进行更多比较。给定具有N个元素的数据集:
N * logN
N * N
成比例。随着N越大N * N
大于N * log N
,无论比例常数。
假设数据集和元素类相同,如果进行更多比较,则需要更多的CPU时间。
另一点需要注意的是,排序算法执行的比较次数通常与算法的其他CPU开销成比例。这意味着使用比较计数作为排序算法整体复杂性的代理,通常安全(虽然不是数学上的声音)。
答案 1 :(得分:0)
为什么比较相对消耗的数组的2个元素
正如Stephen C的回答中提到的,相对于什么?
选择排序和插入排序具有时间复杂度O(n ^ 2),而合并排序具有时间复杂度O(n log(n)),因此对于相当大的n,合并排序将更快,但不是因为比较与O(n ^ 2)排序相比的开销。
对于优化编译器上的合并排序,其中比较元素被加载到寄存器中(假设元素适合寄存器),则比较开销很小,因为移动将写入加载到寄存器中的值而不是读取它再次来自记忆。
对于比较开销,如果对基元数组进行排序,则使用索引来访问基元,但是如果对对象数组进行排序(通常实现为指向对象的指针数组),则比较开销会增加,因为取消引用指针。这会影响快速排序与合并排序的比较(更多移动,更少比较),但合并排序与插入排序或选择排序的问题是O(n ^ 2)时间复杂度与合并排序O(n log(n) ))时间复杂度。
在对对象数组进行排序的情况下,还存在对指针进行排序与对对象排序的问题,这是缓存局部性问题。根据对象的大小,最好对对象进行排序而不是对指针进行排序,但这与原始问题中提出的比较开销并不相关。