第四课:审判程序的灵魂

            算法效率的度量
 事后统计法
   比较不同算法对同一组输入数据的运行处理时间
 缺陷
   为了获得不同算法的运行时间必须编写相应程序
   运行时间严重依赖硬件以及运行时的环境因素
   算法的测试数据的选取相当困难
事后统计法虽然直观,但是实施困难且缺陷多,一般不予考虑。

 

 

程序效率估算练习
二重循环估算

#include <stdio.h>

int func(int a[], int len)
{
    int i = 0;//1
    int j = 0;//1
    int s = 0;//1
    
    for(i=0; i<len; i++)   // n
    {
        for(j=0; j<len; j++)    // n
        {
            s += i*j;
        }
    }
    
    return s;    //  1
}

int main()
{
    int array[] = {1, 2, 3, 4, 5};
    
    printf("%d\n", func(array, 5));
    
    return 0;
}

最后得到n^2+4的复杂度

随着n的增大,在数学上我们可以把次要部分舍去,只看最高幂。

算法效率的度量

最坏与最好

在没有特殊说明时,我们所分析的算法的时间复杂度都是指最坏时间复杂度 。


算法的空间复杂度

空间复杂度估算 :

long sum1(int n)
{
    long ret = 0;// 4 byte
    int* array = (int*)malloc(n * sizeof(int)); // 4 + 4 * n  byte
    int i = 0;// 4 byte
    
    for(i=0; i<n; i++)
    {
        array[i] = i + 1;
    }
    
    for(i=0; i<n; i++)
    {
        ret += array[i];
    }
    
    free(array);
    
    return ret;
}

空间复杂度是看语句所占用的内存空间,这里 int ret和 i分别占用四个字节,在32位编译器上,指针 array占用4字节,最后后malloc  4*n字节的内存,所以空间复杂度为 4n+12。

空间与时间的策略

空间换时间 :

#include <stdio.h>

/*
    问题: 
    在一个由自然数1-1000中某些数字所组成的数组中,每个数字可能出现零次或者多次。
    设计一个算法,找出出现次数最多的数字。
*/

void search(int a[], int len)
{
    int sp[1000] = {0};
    int i = 0;
    int max = 0;
    
    for(i=0; i<len; i++)    //   n
    {
        int index = a[i] - 1;
        
        sp[index]++;
    }
    
    for(i=0; i<1000; i++) //1000
    {
        if( max < sp[i] )
        {
            max = sp[i];
        }
    }
    
    for(i=0; i<1000; i++) // 1000
    {
        if( max == sp[i] )
        {
            printf("%d\n", i+1);
        }
    }
}

int main()
{
    int array[] = {1, 1, 3, 4, 5, 6, 6, 6, 2, 3};
    
    search(array, sizeof(array)/sizeof(*array));
    
    return 0;
}

 这个找出现次数最多的算法,时间复杂度为O(n),牺牲了空间,开辟了一个大数组。

 

大O eg:

这个的时间复杂度是多少?

求项数和,最后得到O(log 2n)。

posted @ 2017-07-12 10:11  Crystal_Guang  阅读(392)  评论(0编辑  收藏  举报