1. 程式人生 > 其它 >【資料結構&演算法】03-複雜度分析之淺析最好、最壞、平均、均攤時間複雜度

【資料結構&演算法】03-複雜度分析之淺析最好、最壞、平均、均攤時間複雜度

目錄

前言

主要記錄四個複雜度分析知識點:

  1. 最好情況時間複雜度 (best case time complexity)
  2. 最壞情況時間複雜度 (worst case time complexity)
  3. 平均情況時間複雜度 (average case time complexity)
  4. 均攤時間複雜度 (amortized time complexity)

李柱明部落格:https://www.cnblogs.com/lizhuming/p/15487280.html

最好、最壞情況時間複雜度

最好情況時間複雜度就是,在最理想的情況下,執行這段程式碼的時間複雜度 。

最壞情況時間複雜度就是,在最糟糕的情況下,執行這段程式碼的時間複雜度 。

例子:在一個連結串列中找出合適的節點:

  • 最好:遍歷該連結串列時,第一個就合適了,那時間複雜度為 O(1)。
  • 最壞:遍歷該連結串列時,全遍歷了,那時間複雜度就為 O(n)。

平均情況時間複雜度

最好和最壞的情況都是極端的,出現的概率不高。

通用的就算平均情況時間複雜度。

計算方法

把每一種情況的時間複雜度全部加起來再除以情況總數。

若考慮每種情況的概率,那就把每種情況的時間複雜度都乘以當前情況的概率然後再除以情況總數。

分析過程

分析遍歷連結串列這個例子(看到最後)

假設連結串列長度為 n,情況有 n+1 種:n 種在連結串列不同位置和一種不在連結串列中。

按照平均時間複雜度的計算方法得出以下結果:

按照大 O 表示法,忽略掉係數、低階和常量,得出的平均時間複雜度為 O(n)。

上述方法並不是很準確,因為每種情況出現的概率並不一樣,若把各種情況發生的概率也考慮進去,分析過程為

假設在陣列中與不在陣列中的概率都為 1/2。

資料出現在 0~n-1 這 n 個位置的概率也是一樣的,為 1/n。

這個值就是概率論中的 加權平均值 ,也叫作 期望值 ,所以平均時間複雜度的全稱應該叫加權平均時間複雜度或者 期望時間複雜度

使用大 O 表示法,其時間複雜度是 O(n)。

均攤時間複雜度

大部分情況下,我們並不需要區分最好、最壞、平均三種複雜度。

平均複雜度只在某些特殊情況下才會用到,而均攤時間複雜度應用的場景比它更加特殊、更加有限。

例子

// array 表示一個長度為 n 的陣列
// 程式碼中的 array.length 就等於 n
int[] array = new int[n];
int count = 0;

void insert(int val)
{
   if (count == array.length)
   {
      int sum = 0;
      for (int i = 0; i < array.length; ++i)
      {
         sum = sum + array[i];
      }
      array[0] = sum;
      count = 1;
   }

   array[count] = val;
   ++count;
}

通過程式碼分析得:

  • 功能:把所有傳入的數值求和儲存到 array[0]

    • 把 val 值儲存到 array 陣列中。
    • 當陣列放滿以後,把陣列 array 中已使用空間的各值總和儲存到 array[0],然後重新開始。

該函式的時間複雜度分析

  • 最好:O(1):

    • 在 array 陣列還有可用空間時。
  • 最壞:O(n):

    • 在 array 陣列沒有可用空間時。
  • 平均:O(1):

    • 每種情況的概率出現都一樣,即是不用考慮概率論。
    • 未滿時每種情況的時間複雜度為 O(1);共 n 種。
    • 滿時情況的時間複雜度為 O(n);共 1 種。
    • (O(1)*n+O(n)) /(n+1)= O(1)
  • 均攤:O(1):

    • 由於這個例子的各種情況的出現是有規律的:n-1 次 O(1) 後會出現一次 O(n) 。按照這種情況,可以把這一次 O(n) 均攤到前面的 n-1 次中,即是每種情況都加上 O(n)/(n-1) = O(1) 。

均攤的應用場景

由於只有在特殊的情況下才使用到均攤,所以列出一些常用的場景即可。如下:

對一個數據結構進行一組連續操作中,大部分情況下時間複雜度都很低,只有個別情況下時間複雜度比較高,而且這些操作之間存在前後連貫的時序關係。

這個時候,我們就可以將這一組操作放在一塊兒分析,看是否能將較高時間複雜度那次操作的耗時,平攤到其他那些時間複雜度比較低的操作上。

在能夠應用均攤時間複雜度分析的場合,一般均攤時間複雜度就等於最好情況時間複雜度。