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