这个插入排序实现最坏的情况是O(n)吗?

时间:2018-11-12 17:21:06

标签: c++ sorting insertion-sort

我知道插入排序应该是最坏的情况O(n ^ 2),但是我想知道为什么以下实现不是O(n)。

void main()
{
//insertion sort runs from i = 1 to i = n, thus is worst case O(n)
for (

    int i = 1,
    placeholder = 0,
    A[] = { 10,9,8,7,6,5,4,3,2,1 },
    j = i;

    i <= 10;

    j-- > 0 && A[j - 1] > A[j]
    ? placeholder = A[j], A[j] = A[j - 1], A[j - 1] = placeholder
    : j = ++i
)

{
for (
    int x = 0;
    x < 10; x++
) 
    cout << A[x] << ' ';
    cout << endl;
}


system("pause");
}

这里只涉及一个for循环,它从1到n。在我看来,这就是O(n)的定义。我到底在这里想念什么?

3 个答案:

答案 0 :(得分:0)

那是一种非常奇怪的代码编写方式,但是定义中有2个for循环。不一定总是有嵌套循环才能拥有O(n ^ 2),也可以通过递归来获取它。 简单来说,O(n ^ 2)n只是表示输入大小为n时执行的操作数。

答案 1 :(得分:0)

草率的术语导致许多人得出错误的结论。这似乎是一个例子。

  

这里只涉及一个for循环,它从1到n。

是的,只有一个循环,但是您所指的“循环”是什么?我确实的意思是让您考虑一下。应该“它”指的是循环吗?这将与相当普遍但草率的术语使用相匹配,但是循环不会求值。因此,循环实际上无法从一个值运行到另一个值。在较简单的情况下可以忽略草率,但在您的情况下则不能。

通常,“ it”实际上是指loop control variable。对于一个简单的循环,例如for (int i = 0; i < 10; ++i),循环的迭代与分配给控制变量的值(在我的示例中为i)之间存在一一对应的关系。因此,存在一个等价关系,当一个人真正表示控制变量时,就可以引用该循环。说一个循环从x到y确实意味着控制变量从x到y,并且每个分配给该控制变量的值都有一个循环迭代 >。此对应关系在您的代码中失败。

在您的循环中,从1到n的是i。但是,i不会随着循环的每次迭代而增加,因此“ 不是对您的循环的准确评估是“从1到n”。当i为1时,最多进行2次迭代。这不是迭代与i的值之间的一一对应关系。随着i的增加,一对一的差异也增大。 i的每个值都可能对应于i+1迭代,因为ji倒数到0。最坏情况下n个条目的迭代总数是i的每个值的潜在迭代总数:2 + 3 +⋯+(n + 1)=(n²+ 3n)/ 2。那是O(n²)。

故事的寓意:编写紧凑的密码不会神奇地改变所实现算法的复杂性。隐秘代码会使复杂性难以确定,但是您所要做的主要事情是使代码更难阅读。

答案 2 :(得分:-2)

给出的代码不是正确的c ++代码,甚至都不接近伪代码。 正确的代码应如下所示:

void main()
{
 int i,j,key;
 int A[]={10,9,8,7,6,5,4,3,2,1};
 //cout<<"Array before sorting:"<<endl;
 //for(i=0;i<10;i++)
 //cout<<A[i]<<"\t";
 //cout<<endl;
 for(i=1;i<10;i++)
 {
  key=A[i];
  for(j=i-1;j>=0 && A[j]>key;j--)
  {
   A[j+1]=A[j];
  }
  A[j+1]=key;
 }
 //cout<<"Array after sorting:"<<endl;
 //for(i=0;i<10;i++)
 //cout<<A[i]<<"\t";
 //cout<<endl;
}

看,插入排序有两个循环。外循环用于维护键变量,内循环用于将键变量之前的元素与键变量进行比较。因此,最坏情况下的时间复杂度是O(n ^ 2)而不是O(n),因为插入排序的基本算法包含两个循环,在最坏情况下(即数组反转时),两个循环最终都会迭代n次。 。