这是插入排序的两个版本,我从伪代码和一个直接实现一个。我想知道哪个版本占用更多的步骤和空间(即使是一个小空间也很复杂)。
void insertion_sort(int a[], int n) {
int key, i, j;
for(i = 1; i < n; i++) {
key = a[i];
j = i - 1;
while(j >= 0 && a[j] > key) {
a[j+1] = a[j];
j--;
}
a[j+1] = key;
}
}
和这一个
insertion_sort(item s[], int n) {
int i,j;
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;
}
}
}
这是样本排序数组a = {5,2,4,6,1,3}。 在我看来,第二版采取更多步骤,因为它逐个交换数字,而第一个版本在while循环中交换更大的数字然后交换最小的数字。例如: Upto index = 3,两个版本都采用相同的步骤,但是当index = 4时,即交换数字1,则2nd比第一个采取更多的步骤。 你觉得怎么样?
答案 0 :(得分:2)
“步数”对任何事情都不是有用的衡量标准。
是一步吗?一份声明?一种表达?汇编指令? CPU微操作?
也就是说,您的“步骤”将转换为汇编程序然后进行优化,结果指令可能具有不同的(可能是可变的)运行时成本。
您可能会问的明智问题:
正如Rafe Kettler的评论和Arpit的答案所述,这是关于算法如何随着输入大小的增长而缩放
如果你想知道哪个更快(对于某些输入集),你应该只测量它。
如果你只想知道哪个执行更多交换,为什么不写一个swap
函数,每次调用它时都会递增一个全局计数器,然后查找?
答案 1 :(得分:1)
交换次数是错误的术语,您应该计算分配的数量。 swap()扩展为三个赋值,因此你通常在第二个版本中得到更多的赋值而不节省空间(你可能没有第二个版本的密钥,但swap()内部有类似的东西)。
答案 2 :(得分:0)
两个版本都使用两个循环。如此复杂O(n*n)
时间。考虑所有其他语句的常量(1)时间。
答案 3 :(得分:0)
让我们逐行分析。我假设交换的复杂性为3
A)
计算复杂性:
3+(n-1)*(1+1+((n-1)/2)*(1+1+1)*(1+1)+1)=1+(n-1)*(3n)=3n^2-3n+1
(我们使用n / 2,因为它似乎是连续最坏情况的平均值)。
内存: 3个整数,+ 1个(循环)
b)中 计算复杂度:2+(n-1)(1 +((n-1))/ 2(1 + 1 + 1)(3 + 1))= 2+(n-1) *(6N-5)= 6N ^ 2-11n + 7
内存: 2个整数,+掉期成本(最可能是1个整数)
不计算输入内存,因为在两种情况下它都是相同的。 希望它有所帮助。