最好、最坏、平均、均摊时间复杂度
实例代码:
//全局变量,大小为10的数组 array,长度 len,下标 i。
int array[] = new int[10];
int len = 10;
int i = 0;
//往数组中添加一个元素
void add(int element){
if(i > len){//数组空间不够了
//重新申请一个2倍大小的数组空间
int new_array[] = new int[len*2];
//把原来 array 数组中的数据依次 copy 到 new_array
for(int j = 0; j < len; ++j){
new_array[j] = array[j];
}
// new_array复制给 array,array现在大小就是2倍 len
array = new_array;
len = 2 * len;
}
//将 element 放到下标为i的位置, 下标 i 加一
array[i] = element;
++i;
}
以上代码中, 10次调用以后,数组长度变为20,紧接着执行一轮10次拷贝操作
再10次调用之后,数组长度变为40,紧接着执行一轮20次拷贝操作
再20次调用之后,数组长度变为80,紧接着执行一轮40次拷贝操作
再40次调用之后,数组长度变为160,紧接着执行一轮80次拷贝操作
再80次调用之后,数组长度变为320,紧接着执行一轮160次拷贝操作
虽然每次数组变化的长度都不一样,都是以两倍的形式扩张。
但是,以上过程可以抽象如下:
不考虑第一次特殊情况,每次数组倍增之前,函数都会被调用n/2(O(1))次,倍增时执行一轮n次(O(n))拷贝操作。
根据以上分析:
最好时间复杂度,此时函数调用中未赶上数组倍增,每次时间复杂度都是O(1)(因为此时每次执行时间、执行步数都是固定的)。
最坏时间复杂度,此时函数调用对应赶上数组倍增,此时时间复杂度是O(n)(除了拷贝,其他操作都是固定步数,复杂度为O(1),根据加法准则,时间复杂度按最高标准计算)
平均时间复杂度:
计算平均执行步数:
以上,每次数组倍增前,都要被调用次O(1),当n趋向于无穷大时,值趋近与常数,因此平均时间复杂度为O(1)
均摊时间复杂度:
均摊时间复杂度就是一种特殊的平均时间复杂度。
摊还分析:
还以上述代码为例:(n/2-1)次O(1),1次 O(n),均摊下来,常量级的时间复杂度,最终均摊时间复杂度就是O(1)