以前對這方面是一知半解,終於在一次大眾點評的筆試中受到刺激。
步入正題:什麼樣的演算法才是高效的演算法?想必所有的人都這麼想過:用最少的錢,花做最短的時間,買到最多的東西。同樣,用最少的記憶體空間,花最短的時間解決問題的演算法就是。因此我們考慮用時間和空間來衡量乙個演算法的效率。
首先我們來考慮如何利用時間來衡量演算法效率。比較容易想到的方法時,可以利用計算機計時的功能,來計算不同演算法的效率。在此基礎上衍生了幾種方法:
咋眼一看,感覺好簡單啊。但是問題來了:首先必須必須根據演算法編寫好程式,通常這會花掉很多時間。對於有些糟糕的演算法,這無疑是中時間上的浪費。其次,這種方法受環境影響太大,主要是硬體環境和軟體環境。我們很難模擬兩種完全一樣的執行環境。最後,測試演算法的資料設計比較麻煩。尤其是在需要的測試據 的模很大的時候,顯得非常麻煩。
總之,這種事後統計的方法太過於麻煩,因此不考慮。
統計發現用高階語言編寫的程式執行時所消耗的時間主要受這幾方面影響:
演算法採用的策略,這是演算法好壞的根本。
編譯產生的**質量
問題輸入規模
機器硬體環境,主要是執行指令速度。
拋開硬體和軟體等因素,單純的懂演算法來考慮,我們發現,乙個程式的好壞依賴於演算法策略和輸入規模。
程式執行所耗費的時間主要是用來執行指令,因此,測定執行時間最可靠的方法時計算對執行時間有消耗的基本操作執行的次數。當然,我們該想到執行的時間和執行的次數成正比。最終,我們將衡量程式執行的時間轉換為計算基本操作的次數。
現在開始正式說說演算法的時間複雜度:分析演算法時,語句總的執行次數t(n)是關於問題規模n的函式,進而分析t(n)隨n的變化情況並確定t(n)。演算法的時間複雜度也就是演算法的時間量度,記作t(n)=o(f(n))。它表示問題輸入規模n的增大,演算法執行時間的增長率和f(n)的增長率相同,因此稱作漸近時間複雜度,也稱作時間複雜度。至於f(n)是問題規模n的某個函式。(要注意,我們時間複雜度並直接等於語句執行次數,這裡千萬不要弄混)
為了方便記憶,我們用大寫o()來表示時間複雜度啦,叫做大o記號。
通常來說,n越大,而t(n)增長最慢的演算法屬於最優演算法。
這裡我們來說一下經常遇見的幾個時間複雜度:
o(1):常熟階
o ( n ):線性階
o(n2
):平方階
在分析乙個演算法時,如何分析器時間複雜度呢?也就是如何推導大o階?
推導規則:
用常數1取代執行時間中所有加法常數。
其次,只保留最高端項。如果階項係數存在且不為1,則去掉這個係數。
最終得到的就是大o階。
下面我們來舉例說明:
int sum=0,n=300;//執行一次
sum=(1+n)*n/2;//執行一次
printf("%d",sum);//執行一次
演算法執行次數的函式f(n)=3.根據上面的推導規則,將常數項改為1。在保留最高項時發現沒有最高項,因此這個演算法時間複雜度為o(1)。
有人納悶為什麼不是o(3)?這裡就是我們剛才提到的要注意的地方。我們只是用執行次數來衡量時間複雜度,但執行次數並不等於時間複雜度。事實上,無論輸入規模n為多少,執行的時間總是恆定的,時間複雜度總為o(1),也成為常數階。
要分析演算法時間複雜度,關鍵是分析迴圈結構的運**況。
int i;
for(i=0;i=n;i++)
}每執行一次外迴圈,內迴圈都執行n次。因此最終執行次數為n*n。時間複雜為o(n2)
。 再看下面:
int i,j;
for(i=0;ifor(j=i;jprintf("%d",j*i);//時間複雜度為o(1)的程式步驟序列}
當i=0時,內迴圈執行n次。
當i=1時,內迴圈知心n-1次
i=n-1時,內迴圈執行1次
因此執行總數為:n+(n-1)+(n-2)······+1=n*(n+1)/2=n2/2+n/2;
根絕推導規則,時間複雜度也為o(n2)。
總結一下常見的時間複雜度。
上面談到除了考慮時間,還要考慮空間,因此提出空間複雜度。所謂的演算法空間複雜度通過計算演算法所需的儲存空間實現,演算法空間複雜度的計算公式:s(n)=o(f(n)),其中n為問題的規模,f(n)為語句關於n所佔儲存空間的函式。
一般情況下,程式執行時,不但需要儲存程式本身的指令、變數以及輸入資料之外,還需要儲存執行過程中對資料操作的儲存單元。假如說,存入的資料所佔的空間和演算法無關,這種情況下,只需要計算該演算法在實現時所需要的輔助單元即可。在演算法執行過程中,如果需要的輔助空間無論在輸入規模n為多大時,總是不變的,那麼此演算法的空間複雜度便是o(1)。
總之,用時間複雜度來指執行時間的需求,使用空間複雜度指空間需求。通常我們說的時間複雜度指的是時間複雜度。
演算法效率度量 時間複雜度和空間複雜度
演算法效率的度量是通過時間複雜度和空間複雜度來描述的。乙個語句的頻度是指該語句在演算法中被重複執行的次數。演算法中所有語句的頻度之和記作t n 它是該演算法問題規模n的函式,時間複雜度主要分析t n 的數量級。演算法中的基本運算 最深層迴圈內的語句 的頻度與t n 同數量級,所以通常釆用演算法中基本...
演算法競賽時間複雜度及空間複雜度
眾所周知 在演算法競賽以及有關電腦科學的諸多學科中,時間複雜度和空間複雜度是評判乙個演算法 程式的重要標準。一般使用o 來表示。同一問題可用不同演算法解決,而乙個演算法的質量優劣將影響到演算法乃至程式的效率。演算法分析的目的在於選擇合適演算法和改進演算法。空間複雜度 space complexity...
時間複雜度及空間複雜度
一.時間複雜度 時間複雜度實際就是乙個函式,該函式計算的是執行基本操作的次 數,而不是程式執行時間。1.在實際中通常關注的是演算法的最壞運 況。乙個演算法的最壞情況的執行時間是在任意輸入下的執行時間上界。一般情況下使用o漸進表示法來計算演算法的時間複雜度。2.書寫方式 例1 void test in...