0

我为插入排序编写了以下代码。我决定通过函数调用来编写代码,而不是传统方法。但我无法找到代码的复杂性。请帮我找出时间和空间的复杂性,以及与传统方法有多少不同。

#include <stdio.h>

void printArray(int ar_size, int *  ar){
    int j;
    for(j=0; j<ar_size; j++)
                printf("%d ", ar[j]);

        printf("\n");
}
void insertion(int ar_size, int *  ar, int p) {
    int last = p, j;
    int v = ar[last];

    for(int i=last; i>=0; i--){
        if(ar[i-1] > v){
            ar[i] = ar[i-1]; 
        }
        else{
            ar[i] = v;
            break;
        }     
    }
    printArray(ar_size, ar);
}

void insertionSort(int ar_size, int *  ar) {
    int i;
    for(i=1; i<ar_size; i++){
        insertion(ar_size, ar, i);
    }
}

int main(void) {

   int _ar_size;
scanf("%d", &_ar_size);
int _ar[_ar_size], _ar_i;
for(_ar_i = 0; _ar_i < _ar_size; _ar_i++) { 
   scanf("%d", &_ar[_ar_i]); 
}

insertionSort(_ar_size, _ar);

   return 0;
}

以下是插入排序的传统方法:

void InsertionSort(int a[], int n)
{
    int i,j, temp;
    for(i=0; i<=n-1; i++)
    {
        temp = a[i];
        j = i;
        while(a[j-1] > temp && j>=1)
        {
            a[j] = a[j-1];
            j--;
        }
        a[j] = temp;
    }   
}
4

1 回答 1

0

您的代码的时间复杂度仍然是 O(n²)。将 for 循环的内部移动到insertion函数中不会改变复杂性。如果您将insertion函数的内容复制并粘贴到调用它的循环中,则代码的运行时间不会有任何差异(事实上,作为优化的一部分,编译器可能会在编译时为您执行此操作)。

如果您以这种方式查看您的代码,您会注意到它在功能上基本上等同于您提供的参考代码。

  1. 参考代码有一个从 0 到数组大小的外循环,你的也是。
  2. 参考代码的内部循环从数组中的当前位置循环到开头,或者直到找到更小的元素。您的代码调用了一个函数,该函数继续执行此操作,只是在更多代码行中。

在功能上,您的代码本质上与引用插入排序实现相同;两者都具有相同的时间复杂度,并且会以完全相同的一系列步骤对数组进行排序。但是,参考实现可能会稍微快一些,仅仅是因为它没有做太多的变量赋值,并且避免使用函数调用。

在启用优化的情况下进行编译(默认情况下)应该使两段代码几乎相同。

于 2015-05-23T08:13:55.237 回答