【问题标题】:Shell sort worst case time complexityShell排序最坏情况时间复杂度
【发布时间】:2015-09-18 17:10:58
【问题描述】:

我想通过此代码了解 shell 排序的最坏情况分析。各位大神能帮我看看吗? while 循环将执行 O(log n) 次,for 循环 O(n) 次;那么复杂性是如何出现的 O(n^2) 呢?一个完整的答案将不胜感激;我已经坚持了一天。

int i, n = a.length, diff = n/2, interchange, temp;
while (diff > 0) 
{ 
  interchange=0;
  for (i = 0; i < n - diff; i++) 
  {
    if (a[i] > a[i + diff]) 
    { 
      temp = a[i];
      a[i] = a[i + diff];
      a[i + diff] = temp;
      interchange = 1;
    }
  }

  if (interchange == 0) 
  {
    diff = diff/2;
  }
}

【问题讨论】:

  • 这似乎不是重复的。我经历了那个,代码和查询都有区别。请不要重复

标签: java algorithm performance shell time-complexity


【解决方案1】:

您的算法不是 shell 排序。壳牌排序通过多次执行基本的冒泡排序来工作。每次,您只考虑它们之间有 k 个元素间隙的元素。 k 由以 1 结尾的递减序列给出。您的序列是 n/2、n/4、n/8、...、1,这很好。但是你没有对这个序列的每个成员执行冒泡排序;您只执行一次传球,这还不够。 O(n^2) 的最坏情况复杂度是由冒泡排序引起的。

请注意,在您的情况下,由于序列没有恒定长度,如果您修复算法,最坏情况的复杂度将是 O(n^2 * logn)。

有关算法的更多详细信息,wikipedia 是您的朋友。

后期编辑:

更正后的代码是:

int i,n=a.length,diff=n/2,interchange,temp;
 while(diff>0) { 
 interchange=0;
 for(i=diff; i<n;i++) {
    temp=a[i];
    for (j = i; j >= gap && a[j-gap] > temp; j -= gap)
      a[j] = a[j-gap];  
    a[j]=temp;
  }
  diff=diff/2;
 }

请注意,我没有检查它,所以我可能错了。现在,你能看到复杂度为 O(n^2) 的嵌套 for 循环吗?

【讨论】:

  • 您能否通过查看我的代码来帮助我了解您是如何到达的。我只是想了解您是如何计算的。
  • 你是如何为我的这段代码计算 O(n^2 * logn) 的。这就是我想知道的。我已经疯了一整天来理解计算这个。非常感谢
  • 请回答上述问题。非常感谢
  • 您的代码错误。您应该在该 while 中有 2 个嵌套的 for 循环,而不仅仅是一个。检查提供的维基百科链接。
  • 您能在 1 个回答中更正并解释上述问题吗
【解决方案2】:

您正在查看的问题是您混淆了平均情况和最坏情况。在一般情况下,diff 会定期更新并划分,导致 while 循环执行接近 lgn 次。但是,由于数据交换,您有机会在每个循环中交换变为 1。如果数据以最坏的方式排序,每个循环都会移动数据。这将导致 while 循环执行 n 次而不是 lgn。在 o(n) 处使用 while 循环和 for 循环,您正在查看 o(n^2)

考虑对长度为 4 的数组进行排序。数字:4、3、2、1。

第一个循环,您找到并切换 4 和 2,以及 3 和 1。这使您的循环:2、1、4、3。

下一个循环,什么都没有发生,交换为 0,所以它将你的差异减半。

第三次循环,你找到并切换 2 和 1,以及 4 和 3:1、2、3、4

Interchange 是 1,diff 仍然是 1,所以你做另一个循环。没有任何反应,退出循环后 diff 变为 0.5。

在这种情况下,while 循环执行 n 次,而 for 循环执行 n 次。

【讨论】:

  • 值得注意的是,shell 排序使用增量计数器仅比较每个 Kth 元素。由于您正在比较每个元素,因此它更像是冒泡排序而不是壳排序。这是因为您的 for 循环递增 1。如果您在理解 shell 排序方面需要帮助,这应该会有所帮助:interactivepython.org/runestone/static/pythonds/SortSearch/…
  • 我是通过例子理解的。但是你是怎么简单地通过代码来达到这个目的的,这花了我一整天的时间。 Ì 想通过查看代码来学习这种到达的艺术。同样使用相同的代码,你能得出平均和最好的情况吗?
  • 我一定会看的。但是你能帮我计算方法以及你是如何得出最佳和平均案例的吗
  • 在处理此类问题时要考虑的事情是,您不能假设您希望循环工作的方式就是它必然会工作的方式。我们希望它运行 O(lgn) 次,因为我们实际上只在 O(lgn) 循环上执行操作。但是,由于所讨论的循环基于一个不会更新每个循环的变量,因此我们必须确认我们期望的这种行为确实发生了。在这种情况下它不会。
  • 最好的和平均的情况也请一并
猜你喜欢
  • 2012-01-12
  • 1970-01-01
  • 2018-01-28
  • 1970-01-01
  • 2015-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多