数据结构与算法系列—最好、最坏、平均、摊还时间复杂度

实例代码

在数组array中查询元素x的下标。

// 在数组array中查询元素x的下标。n表示数组array的长度
int find(int[] array, int n, int x) {
  int i = 0;
  int pos = -1;
  for (; i < n; ++i) {
    if (array[i] == x) {
       pos = i;
       break;
    }
  }
  return pos;
}

最好、最坏时间复杂度

最好情况时间复杂度就是,在最理想的情况下,执行这段代码的时间复杂度。

最坏情况时间复杂度就是,在最糟糕的情况下,执行这段代码的时间复杂度。

上面这段代码中,最好的情况是在数组的第一个元素就找到x,所以最好时间复杂度是O(1)。

最糟糕的情况是在数组的最后一个元素才找到x,所以最坏时间复杂度是O(n)。

平均时间复杂度

上面这段代码,要查找的变量x在数组中的位置,有n+1种情况:在数组的0~n-1位置中和不在数组中。

我们把每种情况下,查找需要遍历的元素个数累加起来,然后再除以n+1,就可以得到需要遍历的元素个数的平均值,即:

(1 + 2 + ... + n + n)/ (n + 1) = n(n + 3) / 2(n + 1)

时间复杂度的大O标记法中,可以省略掉系数、低阶、常量。

所以,这个公式简化之后,得到的平均时间复杂度就是O(n)。

摊还时间复杂度

在下面这段代码中,只有在某种特殊的情况,即i >= len时,时间复杂度才是O(n)。

一般情况下的时间复杂度时O(1)。特殊情况下的时间复杂度可以分摊到每一个一般情况下。

因此,摊还时间复杂度为O(1)。

// 全局变量,大小为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;
}
posted @ 2020-04-07 10:25  limaodeng  阅读(562)  评论(0编辑  收藏  举报