我很难理解为什么插入排序的最佳情况在o(n)?
for (int i = 0; i < size; i++) {
for (int j = i; j > 0; j--) {
int k = j-1;
if( a[j] < a[k]){
int temp = a[j];
a[j] = a[k];
a[k] = temp;
}
}
}
让我们考虑一个示例初始数组[1,2,3,4,5] size = 5
第一个循环将从i = 0变为size - 1
第二个循环将从i变为1但是假设,内部for循环也从0变为size - 1换句话说,for for循环也执行(n-1)次类似于外部for循环
我同意没有互换,但会有比较,&amp;它将与未排序的数组完全相等?
然后n-1(外环)* n - 1(内环)= n ^ 2 - n + 1 = O(n ^ 2)
谁能解释我哪里错了?
答案 0 :(得分:6)
首先,这似乎不是插入排序的正确代码。您似乎以相反的方式使用冒泡排序代码 在插入排序代码中,你不会用落在它之前的每个大元素替换一个小元素,而是我们浏览掉落在它之前的所有大元素,并且只有在我们处于没有元素的地方或那里不再是大元素,然后我们将小元素放在那个位置并移动/移动所有其他后续元素。
作为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)个比较。
我希望以上例子澄清你的疑问。
答案 1 :(得分:3)
您的代码始终以O(n ^ 2)运行。在找到元素所在的位置时,你必须打破内部for循环。
答案 2 :(得分:1)
这是实现插入排序的一种方法。
获取输入列表和最初为空的输出列表。
遍历输入列表并将每个项目放在输出列表上的适当位置。从第一个元素开始,遍历输出列表,找到合适的位置。
现在,如果您的输入已经排序,则插入点将始终位于输出列表的开头或结尾。第一种可能性对应于最佳情况;第二个对应最坏情况。
例如,我的输入数据是:4 3 2 1。
然后输出列表构建为:
4
3 4
2 3 4
1 2 3 4
由于查看第一个元素只需要O(1),因此时间复杂度是输入的大小,或O(N)。
答案 3 :(得分:0)
当数组已经排序时,插入排序的最佳情况是 O(n)。
但是你的算法仍然需要O(n ^ 2)来排序。因此,只有在条件失败时才应进入第二个循环。这样,在排序列表的情况下,您将永远不会进入内循环。
检查以下链接:http://www.personal.kent.edu/~rmuhamma/Algorithms/MyAlgorithms/Sorting/insertionSort.htm
答案 4 :(得分:0)
将您的方法更改为具有此中断条件,您将获得最佳案例复杂度O(n)。
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);
}
答案 5 :(得分:0)
考虑以下插入排序实现:
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;
}
}
任何排序算法的最佳情况是输入已按排序顺序排列。在这种情况下,while循环的条件总是返回false,因此它只迭代外部for循环,以O(n)时间复杂度在线性时间内完成工作。