使用选择排序对几乎排序的数组进行排序?

时间:2016-12-22 00:59:54

标签: java arrays algorithm sorting

我正在玩这个网站(https://www.toptal.com/developers/sorting-algorithms/)并点击“Play Nearly Sorted”。我注意到选择排序算法比其他算法慢得多。你能否解释一下为什么会这样,并可能指出我有关于此的更多信息的链接。谢谢!

2 个答案:

答案 0 :(得分:3)

您会注意到,无论数据的初始排序如何,选择排序实际上只需要执行相同数量的步骤。

选择排序可以这样描述(伪代码,假设data是一个长度n的列表,索引从1n包括在内)

for pass = 1 to n {
  //at each pass, find the minimal item in the list (that we haven't already sorted)
  indexMin = pass
  for item = pass + 1 to n {
    if data[item] < data[indexMin] {
      indexMin = item
    }
  }
  swap data[pass] and data[indexMin]
}

就像它的名字所暗示的那样,它反复(事实上是n次)选择最小的元素,然后将它放在正确的位置。这会在每次传递时从位置1到位置pass开始创建一个已排序的子列表。

如您所见,选择排序无法提前终止。在排序时只需采用盲霰弹枪方法。即使在已经完全排序的数组上,它也将始终正好运行n次传递。

其他算法经常“知道”何时完成排序,并且可以提前终止。正如Tim的评论所说,选择排序是一种蛮力方法,永远不会比n^2

更快地运行

答案 1 :(得分:1)

要完全理解常见排序算法的运行时间,需要您阅读其伪代码。在一个近乎排序的案例中,&#34;选择排序是最慢的,因为无论如何,它的运行时间总是O(n ^ 2),它在多项式时间内运行。多项式时间被认为是您所附网站中所有时间复杂度中最慢的。以下是选择排序的代码:

public static void selectionSort(int [] A) {
  for(int i = 0; i < A.length - 1; i++) {
    int min = i;
    for(int j = i + 1; j < A.length; j++){
       if(A[j] < A[min])
         min = j;
    }
  }
  swap(A, i, min);
}

它始终与这两个&#34;用于&#34;无论数组A的排序多少,都会循环。关于其他算法,它们相对更智能&#34; (更快)使用初始数组A,如果它以某种方式或几乎排序。你可以用另一种方式问问自己;为什么插入排序在一个近乎排序的数组中如此之快?&#34;希望这有帮助!