复杂度分析

一曲冷凌霜 提交于 2019-12-24 02:23:15

内容整理自《数据结构与算法之美》 

整理: 

思考:

分析下面这个 add() 函数的时间复杂度


// 全局变量,大小为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;
}

 1.最好情况时间复杂度

最理想的情况下,数组中有空间,直接将数据添加到数组即可,所以最好情况时间复杂度为 O(1)。

 2.最坏情况时间复杂度

最糟糕的情况下,数组中没有空间,需要for循环进行数组的copy,然后再添加数据,所以最坏情况时间复杂度为 O(n)。

 3.平均时间复杂度

假设数组的长度是 n,根据数据插入的位置的不同,我们可以分为 n 种情况,每种情况的时间复杂度是 O(1)。

 除此之外,还有一种“额外”的情况,就是在数组没有空闲空间时插入一个数据,这个时候的时间复杂度是 O(n)。

 而且,这 n+1 种情况发生的概率一样,都是 1/(n+1)。

 所以,O( 1*(1/n+1)+1*(1/n+1)+...+1*(1/n+1)+n*(1/(n+1)) )=O( 1 ),平均时间复杂度是 O(1)。

 4.均摊时间复杂度

O(1) 时间复杂度的插入和 O(n) 时间复杂度的插入,出现的频率是非常有规律的,而且有一定的前后时序关系。

 前n个操作复杂度都是O(1),第n+1次操作的复杂度是O(n),

 所以把n+1的那次操作均摊到 n 次耗时少的操作上,均摊下来,这一组连续的操作的均摊时间复杂度就是 O(1)。

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!