void insertionSort(vector<int>& v){
for(int i =1; i<v.size(); ++i){
int key = v[i];
int j = i - 1;
while(j>=0 && key < v[j]){
swap(v[j], v[j+1]);
j--;
}
v[j+1] = key; // works fine without this.
}
}
在插入排序算法中,我只是想知道为什么插入了注释部分。 我做了几个实验去除那部分,实际上认为可以摆脱它。
有人可以解释这条线的目的吗?任何帮助将不胜感激!
答案 0 :(得分:2)
由于每次交换后它都会j--
,在最终交换之后(释放v[j]
),它再次减少j
。因此,您需要将新元素放在v[j + 1]
。
顺便说一下,此代码不需要交换,您也可以v[j + 1] = v[j]
代替swap
。
修改强>
关于实施的问题,或许作者提出了一个需要swap
的问题 - 在不知道背景的情况下,我们无法肯定地说。
由于没有人真正使用插入排序,我认为这只是理论上的目的,并且可能通过计算交换次数来计算复杂性。因此,作者可能已经使用swap
作为构建块来演示排序。
回到问题,
swap
执行的额外写操作没有问题,则实施正确。(基本上swap(a, b)
是t = a; a = b; b = t;
,因此另外两次写入。)
swap
,那么注释掉的行确实没有必要。如果没有swap
,您可以将其重写为 -
void insertionSort(vector<int>& v){
for(int i = 1; i < v.size(); ++i){
int key = v[i];
int j = i - 1;
while(j >= 0 && key < v[j]){
v[j + 1] = v[j];
j--;
}
v[j + 1] = key; // this is now necessary.
}
}
请注意,由于这会减少仅由常量所取的渐近时间,因此复杂性仍然与swap
的复杂度相同,即$ O(n ^ 2)$。