计算插入排序中的步骤数

时间:2013-03-26 18:21:12

标签: c insertion-sort

这是插入排序的两个版本,我从伪代码和一个直接实现一个。我想知道哪个版本占用更多的步骤和空间(即使是一个小空间也很复杂)。

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比第一个采取更多的步骤。 你觉得怎么样?

4 个答案:

答案 0 :(得分:2)

“步数”对任何事情都不是有用的衡量标准。

是一步吗?一份声明?一种表达?汇编指令? CPU微操作?

也就是说,您的“步骤”将转换为汇编程序然后进行优化,结果指令可能具有不同的(可能是可变的)运行时成本。


您可能会问的明智问题:

1什么是算法复杂度

正如Rafe Kettler的评论和Arpit的答案所述,这是关于算法如何随着输入大小的增长而缩放

2 如何执行

如果你想知道哪个更快(对于某些输入集),你应该只测量它。


如果你只想知道哪个执行更多交换,为什么不写一个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个整数)

不计算输入内存,因为在两种情况下它都是相同的。 希望它有所帮助。