【问题标题】:Does this kind of sorting has any name?这种排序有什么名字吗?
【发布时间】:2019-05-11 23:48:32
【问题描述】:

我编写/使用了这种排序。我只是想知道它是否有任何名称,或者它是否类似于任何现有的排序算法。顺便说一句,它是否有效/有价值?

int s = 20;

int unsorted_array[s];

//(adding numbers to unsorted_array)
//We assume that every number is different to avoid any difficulties.

int i, i2, pos;
int sorted_array[s];

//!!! sorting algo starts here:

for(i=0; i<s; i++){
   pos = 0;
   for(i2=0; i2<s; i2++){

      if(unsorted_array[i] > unsorted_array[i2]){
         pos += 1;
      }
   }

   sorted_array[pos] = unsorted_array[i];

}

那你怎么看?它比其他类型的排序方法慢/快吗?我还在学习。感谢您的任何回复!

【问题讨论】:

  • int unsorted_array[s]; -- 无效的 C++,因为变量 s 用于表示数组的大小。
  • By the way, is it even efficient/worthy or not really? -- 如果您有 1,000 个元素,那么您将循环最坏的情况总共 1,000,000 次。如果有 1,000,000 个元素,那就是 1,000,000,000,000 次迭代。好不好由你来评判。
  • @PaulMcKenzie 大多数 C++ 编译器仍然会接受它作为扩展。

标签: c algorithm sorting


【解决方案1】:

它是否比其他类型的排序方法更慢/更快?

我们来分析the time complexity of this function。随着未排序列表的大小增加,它需要做多少工作?

重要的部分是循环。他们会告诉我们你需要做多少次这件事,这很重要。您的循环可以分解为:

for(1 to s){
   for(1 to s){
       do that thing
   }
}

对于每个元素,它必须重新检查每个元素。如果有 2 个项目,这意味着你做了 4 次。 3 项,9 次。 4 项,16 次。我们说时间复杂度是n^2n 是大小的约定),因为随着大小的增加,步数是平方的。这意味着随着大小的增加,所需的时间将呈指数增长。 10 个项目需要 100 次。 100 件物品需要 10,000 件。 1,000 需要 1,000,000。 n^2 应尽可能避免。

Most sorting algorithms 可以在n * log(n) 或准线性时间内完成他们的工作。随着大小的增加,时间将增加n * log(n)。这比线性快,但比指数慢。 log(n) 通常是 natural logarithmln(n)。 10 个项目大约需要 23 次。 100 大约 460。1000 大约 6900。所以你的算法比较慢。

n * log(n) 以上的算法增长得如此之快,以至于有必要扭曲垂直时间尺度,以便使用性能更好的算法将它们有意义地拟合到同一张图上。

您可以猜到,对于大量项目,拥有性能更好的算法比更快地完成事情更重要。比n log n 快100 倍的n^2 算法将丢失大约600 个项目。

n^2 = 100 n * ln(n)
n = 100 ln(n)
n / ln(n) = 100

【讨论】:

    【解决方案2】:

    在我看来,它就像某种反向选择排序。选择排序会说“什么元素位于位置 0?”然后找到那个元素。您的排序似乎在说“当前位置 0 的元素去哪里了?”,这是一个同样有效的问题。

    就复杂度而言,绝对是O(n^2),它与插入、选择、冒泡等其他“低效”方案相提并论,低于合并或快速等更复杂的“更好”方案.我最关心的主要问题是你实际上迭代n^2 次,而像插入或选择这样的算法可以逃脱n (n + 1) / 2(三角形数字,而不是方形数字),这是相同的复杂性类,但总体数量较少。此外,您的排序要求我们在内存中提出一个新数组,而许多现有数组(特别是插入和选择,因为它们有点接近您的)可以在恒定空间中完成,而无需分配任何更多数组。

    【讨论】:

      【解决方案3】:

      这是通过为数组中的每个元素查找小于它的元素数来实现的。这相当于找到它的最终位置。

      O(n*n) 很慢(有不错的O(n*lg(n)) 算法)。但是那里有很多O(n*n) 排序算法,所以你在好公司。

      它也只适用于唯一值,这是一个非常严重的限制。

      它还需要第二个数组来复制它,大多数排序算法都不需要,所以这是另一个缺点。

      它的好处是零交换,并且只有非常少量的实际副本(实际上是n),这在某些情况下可能是一件好事,但这是一个很小的优势。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-23
        • 2010-10-31
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多