我已阅读的消息来源说,选择排序的时间复杂性是:
我想知道它是否值得来优化"该算法通过添加一定代码行来使算法"短路"如果其余部分已经排序,则本身。
这里是用C:
编写的代码我还添加了一条注释,指出哪些行是"优化"一部分。
void printList(int* num, int numElements) {
int i;
for (i = 0; i < numElements; i ++) {
printf("%d ", *(num + i));
}
printf("\n");
}
int main() {
int numElements = 0, i = 0, j = 0, min = 0, swap = 0, numSorted = 0;
printf("Enter number of elements: ");
scanf("%d", &numElements);
int* num = malloc(sizeof(int) * numElements);
for (i = 0; i < numElements; i ++) {
printf("Enter number = ");
scanf(" %d", num + i);
}
for (i = 0; i < numElements-1; i++) {
numSorted = i + 1; // "optimized"
min = i;
for (j = i + 1; j < numElements; j++) {
numSorted += *(num + j - 1) <= *(num + j); // "optimized"
if (*(num + min) > *(num + j))
min = j;
}
if (numSorted == numElements) // "optimized"
break;
if (min != i) {
swap = *(num + i);
*(num + i) = *(num + min);
*(num + min) = swap;
}
printList(num, numElements);
}
printf("Sorted list:\n");
printList(num, numElements);
free(num);
getch();
return 0;
}
答案 0 :(得分:2)
优化选择排序有点傻。它具有可怕的最佳情况,平均时间和最坏情况时间复杂度,因此如果您想要远程优化排序,您(几乎?)总是会选择另一种。即使插入排序往往更快,实现也不会复杂得多。
更重要的是,检查列表是否已排序会增加算法在最坏情况下所采用的时间(我也倾向于考虑平均情况)。即使是排序最多的列表也不一定会更快:考虑1,2,3,4,5,6,7,9,8
。尽管列表最后只需要交换两个元素,但算法不会短路,因为它直到最后都没有排序。
答案 1 :(得分:0)
我看到如何解决这个问题的唯一方法是,如果您定义了为什么要对其进行优化,那么请参见。
我教个人编程,有时我教他们算法和数据结构。我认为选择排序是最容易解释和讲授的方法之一-在解释了找到最小值并交换两个值(swap())的算法后,它自然流动。然后,最后,我介绍了优化的概念,可以在其中实现此计数器“已排序”检测。
毫无疑问,冒泡排序最好引入优化,因为它至少具有3个易于解释和实质性的优化。
答案 2 :(得分:0)
仅仅是因为可以优化某些东西,不一定意味着它应该这样做。假设进行概要分析或“ boss-says-so”表明必须进行优化,那么您可以做一些事情。
与任何涉及内存迭代的算法一样,减少迭代次数的任何方法都可以提供帮助。
它也可以帮助最大化缓存的位置。
在有用且实用的地方使用SIMD指令和寄存器
如果您使用多个最大值/最小值,请优化对最大值和最小值的n个值的排序
还有很多可用的优化方法,但是最终与选择排序的相似性开始变得模糊。这些都会增加复杂性,从而增加维护成本,以使更合适的算法的更简单实现可能是更好的选择。
答案 3 :(得分:0)
我想知道是否有必要通过添加特定的代码行来“优化”算法,如果剩余部分已经被排序,则使算法本身“短路”。 / p>
显然,此更改将最佳情况下的复杂度从O(n 2 )降低到O(n)。对于除O(1)前导元素之外已经排序的输入,将观察到这一点。如果有这种可能,那么建议的代码更改实际上可能会带来可观且值得的性能改进。
但是请注意,您所做的更改使最内层循环中执行的工作增加了一倍以上,并考虑到对于统一的随机输入,预期的外层循环迭代次数为 1 。还要考虑一下,您设法修剪的任何外循环迭代将以其他方式执行的工作最少。总的来说,尽管您没有改变渐近复杂性,但平均情况和最坏情况下的实际性能会明显变差,运行时间是其两倍。
如果您追求更快的速度,那么最好的选择是选择其他排序算法。在比较排序中,插入排序与最佳选择排序在最佳情况下的性能大致相同,但是在最佳情况下的选择范围更广,通常在一般情况下胜过(常规)选择排序。两者在最坏的情况下如何比较取决于实现方式。
如果您仍然想要更好的性能,请考虑合并排序或快速排序,这两种方法都非常容易实现。或者,如果您的数据适合它,那么计数排序就很难被击败。