Algorithm 为什么插入排序的最佳情况是O(n)&;不是O(n^2)?
我很难理解为什么o(n)中插入排序的最佳情况Algorithm 为什么插入排序的最佳情况是O(n)&;不是O(n^2)?,algorithm,sorting,Algorithm,Sorting,我很难理解为什么o(n)中插入排序的最佳情况 for(int i=0;i0;j--){ int k=j-1; if(a[j]11,因此无需再查看落在11之前的元素。 第3步:以元素15为例,查找落在它之前的元素(即元素13),如15>13,因此无需再查看落在13之前的元素。 步骤4:以元素17为例,查找落在它前面的元素(即元素15),如17>15,因此无需再查看落在15之前的元素。 第5步:以元素19为例,查找落在它之前的元素(即元素17),如19>17,因此无需再查看落在17之前的元素 正如我
for(int i=0;i0;j--){
int k=j-1;
if(a[j]
让我们考虑一个示例初始数组[1,2,3,4,5]大小=5。
第一个循环将从i=0变为大小-1
第二个循环将从i变为1,但让我们假设,内部for循环也从0变为大小-1,换句话说,内部for循环也会执行(n-1)次,类似于外部for循环
我同意不会有交换,但会有比较&它将完全等同于未排序的数组?
然后n-1(外环)*n-1(内环)=n^2-n+1=O(n^2)
有人能解释一下我错在哪里吗?这里有一种实现插入排序的方法 获取一个输入列表和一个初始为空的输出列表 迭代输入列表,并将每个项目放在输出列表上的适当位置。从第一个元素开始,遍历输出列表,找到适当的位置 现在,如果输入已排序,则插入点将始终位于输出列表的开头或结尾。第一种可能性对应于最佳情况情景;第二种情况对应于最坏情况 例如,我的输入数据是:4 3 2 1 然后,输出列表构建为:
4
3 4
2 3 4
1 2 3 4
由于查看第一个元素只需要O(1),因此时间复杂度取决于输入的大小,即O(N)。您的代码始终以O(N^2)运行。在找到元素应该位于的位置时,必须中断内部for循环。插入排序的最佳情况是当数组已经排序时O(n) 但是,对于排序的情况,您的算法仍然需要O(n^2)。所以,只有当条件失败时,才应该进入第二个循环。这样,在排序列表的情况下,您将永远不会进入内部循环 查看以下链接:
首先,这似乎不是用于插入排序的正确代码。您似乎正在以相反的方式使用冒泡排序代码。
在插入排序代码中,您不会将一个小元素替换为它前面的每个大元素,而是浏览它前面的所有大元素,仅当我们处于没有元素留下或没有更多大元素的位置时,然后我们将小元素放置在该位置,并移动所有其他后续元素 作为O(n)时间的一部分:
让我们考虑五个已经排序的元素的数组——ARR[11,13,15,17,19]。我们从第一个位置元素移动到最后一个位置。
第1步:接受元素11,因为它是第一个元素,所以我们保持原样。
第2步:以元素13为例,查找落在它之前的元素(即元素11),如13>11,因此无需再查看落在11之前的元素。
第3步:以元素15为例,查找落在它之前的元素(即元素13),如15>13,因此无需再查看落在13之前的元素。
步骤4:以元素17为例,查找落在它前面的元素(即元素15),如17>15,因此无需再查看落在15之前的元素。
第5步:以元素19为例,查找落在它之前的元素(即元素17),如19>17,因此无需再查看落在17之前的元素 正如我们所看到的,对于五个已经排序的元素,我们只需要5个比较,因此对于'n'排序的元素,我们只需要O(n)个比较。
我希望上面的例子能澄清你的疑问 将方法更改为具有此中断条件,您将获得最佳案例复杂性O(n)
void insertionSort0(列表)
{
int循环=0;
对于(int i=1;i=0;j--)
{
loop++;
if((整数)list.get(j)>target)
{
set(j+1,(整数)list.get(j));
pos=j;
}
其他的
{
打破
}
}
列表。设置(位置、目标);
}
System.out.println(“插入排序的循环输入”+循环);
}
考虑以下插入排序的实现:
for (i=1; i<n; i++) {
j=i;
while ((j>0) && (s[j] < s[j-1])) {
swap(&s[j],&s[j-1]);
j = j-1;
}
}
(i=1;i0)和(s[j]{
掉期(s[j]、&s[j-1]);
j=j-1;
}
}
任何排序算法的最佳情况是输入已经按排序顺序进行。在这种情况下,while循环中的条件总是返回false,因此它只对外部for循环进行迭代,以O(n)时间复杂度在线性时间内完成任务 在计算最佳情况复杂度方面没有任何有用的应用。话虽如此,当数组已经排序时,您的算法会浪费时间。每次
a[i+1]>=a[i]
@n.m.时,您都可以跳过内部循环,您说最好的情况没有应用程序,可能最好的情况或接近最好的情况在随机数据中并不经常出现,但随后您继续推荐仅对此类数据有意义的代码更改。在某些情况下,人们希望数据的顺序接近排序,在这种情况下,运行时将更接近O(N)而不是O(N^2)。感谢guyz,我现在理解了我犯错误的地方。他使用的是数组,而不是列表。这里的区别非常无关紧要,@Gumbo.Insertion sort的最佳情况是当值已经按升序排列时。您所描述的是最糟糕的情况,即对于每个插入的值,必须移动所有以前插入的值,这将导致ψ(n^2)。我在这里描述的是插入排序
void insertionSort0(List<Integer> list)
{
int loop=0;
for(int i=1;i<list.size();i++)
{
int target=(Integer)list.get(i);
int pos=0;
for(int j=i-1;j>=0;j--)
{
loop++;
if((Integer)list.get(j)>target)
{
list.set(j+1, (Integer)list.get(j));
pos=j;
}
else
{
break;
}
}
list.set(pos, target);
}
System.out.println("loop in for insertion sort" +loop);
}
for (i=1; i<n; i++) {
j=i;
while ((j>0) && (s[j] < s[j-1])) {
swap(&s[j],&s[j-1]);
j = j-1;
}
}