• 正文
  • 推薦器件
  • 相關(guān)推薦
申請入駐 產(chǎn)業(yè)圖譜

算法時間復(fù)雜度分析:大O表示法

2024/04/03
2990
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

在開發(fā)的時候,我們?nèi)绾卧u估一個算法的好壞,如何描述一個算法運(yùn)行效率的高低呢?通俗一點的表達(dá)方法就是程序執(zhí)行快或慢,但是這只是一種較為寬泛的描述,我們?nèi)绾沃庇^科學(xué)的用的描述它呢?

有同學(xué)可能會說,用其運(yùn)行時間不就可以很好很直觀的描述它了。不過,不同的語言,不同的編譯器,不同的CPU來說,對程序的處理的時間是不同的,我們無法單單用運(yùn)行時間來描述某個算法執(zhí)行效率。另外,當(dāng)需要處理的數(shù)據(jù)增長時,算法的基本操作要重復(fù)執(zhí)行的次數(shù)也會增長,對于不同的算法的增長的速度也不一樣。

數(shù)學(xué)果然是個不錯的工具,為了描述算法的運(yùn)行時間的增長情況,我們可以用不同數(shù)學(xué)公式來分析。在計算機(jī)科學(xué)上,我們是有專門的術(shù)語來表征算法的效率,就是今天要和大家一起學(xué)習(xí)的大O表示法。大O并不是表示算法運(yùn)行需要多長時間,它表示的是算法運(yùn)行時間的增速,即算法的運(yùn)行時間以不同的速度增加,也叫漸進(jìn)時間復(fù)雜度。

我們可以用下面的表達(dá)式來表示:

通常主要有以下幾種表達(dá)式來描述時間復(fù)雜度:

  • O(1):常量時間
  • O(n):線性時間
  • O(log n):對數(shù)時間
  • O(n^2):二次方時間
  • O(2^n):指數(shù)時間
  • O(n!):階乘時間

每種時間復(fù)雜度有所不同,下面我們一起來詳細(xì)了解這幾種時間復(fù)雜度。


大O復(fù)雜度

O(1)

O(1)表示常量時間復(fù)雜度,當(dāng)給定大小為n的輸入,無論n為何值,最后算法執(zhí)行的時間是個常量。舉個例子:

int func(int n)
{
n++;
return n*2;
}

上面的程序中,無論輸入n的值如何變化,程序執(zhí)行時間始終是個常量。我們簡化處理一下,假如函數(shù)中每行語句的執(zhí)行時間是1,則執(zhí)行時間的數(shù)學(xué)表達(dá)式:

無論n為多大,最后的執(zhí)行時間都是2這個固定值。雖然是運(yùn)行時間為2,但是這里我們也用O(1)來表示,這里的1代表是一個常數(shù)。

O(n)

O(n)表示線性時間復(fù)雜度,算法的執(zhí)行時間隨著輸入n的大小成線性變化。

int func(int n)
{
int sum = 0;
for(int i=0; i<n; i++)
{
sum = sum + i;
}

return sum;
}
上面的這個程序中,函數(shù)的執(zhí)行時間隨著n的變化成線性的關(guān)系。

對于這種可以用線性表達(dá)式表示的情況,我們用O(n)來表示。

為什么可以省略掉表達(dá)式中的其他系數(shù)呢?主要是當(dāng)n趨近于無窮大時,系數(shù)相對于無窮大的n來說可以忽略不計。

O(n^2 )

O(n^2)表示二次方時間復(fù)雜度,一個算法的時間將會隨著輸入數(shù)據(jù)n的增長而呈現(xiàn)出二次關(guān)系增加。

int func(int n)
{
int sum = 0;
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
sum = sum + i + j;
}
}

return sum;
}

上面的程序中,是個兩層循環(huán)的程序,函數(shù)的執(zhí)行時間和n是二次方的關(guān)系:

對于這種類型的程序,我們可以用O(n^2)表示。不過,循環(huán)嵌套除了這種兩層循環(huán)之外,還會有三層、四層...n層循環(huán),對應(yīng)的其復(fù)雜度就是O(n^3) 、O(n^4)...O(n^n)。

O(2^n)

O(2^n)表示指數(shù)復(fù)雜度,隨著n的增加,算法的執(zhí)行時間成倍增加,它是一種爆炸式增長的情況。

int func(int n)
{
if(n==0) return 1;

return func(n) + func(n-1)
}

上面的代碼中,有兩次遞歸調(diào)用,函數(shù)的執(zhí)行時間就會和輸入n成指數(shù)的關(guān)系。

因此,這里我們可以用O(2^n)表示。

O(log n)

O(log n)表示對數(shù)時間復(fù)雜度,算法執(zhí)行時間和n是一種對數(shù)關(guān)系。這種類型的算法會在執(zhí)行的過程中,隨著程序的執(zhí)行其完成某個功能的操作步驟越來越少。其中,我們所熟知的二分查找法就是一個很好的例子。比如,下面這個代碼在一個有序列表中查找某個值的位置,我們通過二分法進(jìn)行查找。

int func(int a[], int size, int num)
{
int left = 0;
int right = size-1;

while(left <= right)
{
int mid = (left + right)/2;

if(a[mid] > num)
{
right = mid - 1;
}
else if (a[mid] < num)
{
left = mid + 1;
}
else
{
return num;
}
}

return -1;
}

在最糟糕的情況下,我們通過二分法拆分x次后,最后一個元素就是我們要找的元素。我們可以得到下面的等式:

函數(shù)運(yùn)行時間可以表示為:

因此,這里我們可以用O(log n)表示。

O(n!)

對于階乘關(guān)系的復(fù)雜度,最典型的例子就是旅行商問題。

假設(shè)有一個旅行商人要拜訪n+1個城市,他必須選擇所要走的路徑,路徑的限制是每個城市只能拜訪一次,而且最后要回到原來出發(fā)的城市。路徑的選擇目標(biāo)是要求得的路徑長度為所有路徑之中的最小值。

這個問題最簡單的方法是通過窮舉法列出所有的排列組合。如果有n+1個城市,根據(jù)我們數(shù)學(xué)中學(xué)過的排列組合計算方法,可以算出所有組合數(shù)為n!,所以這種窮舉法對應(yīng)的時間復(fù)雜度也就是O(n!)了。

推薦器件

更多器件
器件型號 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊 ECAD模型 風(fēng)險等級 參考價格 更多信息
SN74LVC1G07DCKR 1 Texas Instruments Single 1.65-V to 5.5-V buffer with open-drain outputs 5-SC70 -40 to 125

ECAD模型

下載ECAD模型
$0.48 查看
ASEM1-16.000MHZ-LC-T 1 Abracon Corporation MEMS OSC XO 16.0000MHZ CMOS SMD
$1.63 查看
ATS08ASM-1E 1 CTS Corporation Parallel - Fundamental Quartz Crystal, 8MHz Nom, GREEN, RESISTANCE WELDED, METAL, HC-49/US-SM, 2 PIN

ECAD模型

下載ECAD模型
$0.59 查看

相關(guān)推薦