函式的漸進增長
我們現在來判斷一下,兩個演算法a和b哪個更好。假設兩個演算法的輸入規模都是n,演算法a要做2n+3次操作,你可以理解為先有乙個n次的迴圈,執行完成後,再有乙個n次迴圈,最後有三次賦值或運算,共2n+3次操作。演算法b要做3n+1次操作,你覺得它們誰更快呢
準確來說,答案是不一定的
當n=1時,演算法a效率不如演算法b(次數比演算法b要多了一次)。而但n = 2時,兩者效率相同,當n>2時,演算法a就開始優於b了,隨著n的增加,演算法a比演算法b越來越好了(執行次數比b要少),不我們可以得出結論,演算法a總體上要好過b。
·此時我們給出這樣的定義,輸入規模n在沒有限制的情況下,只要超過乙個數值n,這個函式就總是大於另乙個函式,我們稱函式是漸進增長的。
從中我們發現,隨著n的增大,後面的+3還是+1其實是不影響最終的演算法變化的,例如演算法a和演算法b,所以我們可以忽略這些加法常數。後面的例子,這樣的常數被忽略的意義可能會更加明顯。
我們來看第二個例子,演算法c是4n+8,演算法d是2n的二次方+1。
當n<=3的時候,演算法c要差於演算法d(因為演算法c次數比較多),但當n>3後,演算法c的優勢就越來越優於演算法d了,到後來更是遠遠勝過。而當後面的常數去掉後,我們發現其實結果沒有發生改變,甚至我們在觀察發現,哪怕去掉與n相乘的常數,這樣的結果也沒發生改變,演算法c的次數隨著n的增長,還是遠小於演算法d,也就是說,與最高次項相乘的常數並不重要。
我們再來看第三個例子。演算法e是2n的二次方+3n+1,演算法f是2n的三次方+3n+1
當n=1時,演算法e和演算法f結果相同,但當n > 1後,演算法e的優勢就要開始優於演算法f,隨著n的增大,差異非常明顯,通過觀察發現,最高慈祥的指數大的,函式隨著n的增長,結果也會變的增長特別快。我們來看最後乙個例子。演算法g是2n的二次方,演算法h是3n+1,演算法i是2n的二次方+3n+1
這組資料應該就看得很清楚,當n的值越來越大時,你會發現,3n+1已經沒法和2n的二次方的結果相比較,最終幾乎可以忽略不計,也就是說隨著n值變得非常大以後,演算法g其實已經很趨近於演算法i。於是我們可以得到這樣乙個結論,判斷乙個演算法的效率時,函式中的常數和其它次要項常常可以忽略,而更應該關注主項的階數。判斷乙個演算法好不好,我們只通過少量的資料是不能做出準確判斷的。根據剛才的幾個樣例,我們發現,如果我們可以對比這幾個演算法的關鍵執行次數函式的漸進增長性,基本就可以分析出:某個演算法,隨著n的增大,它會越來越優於另一演算法,或者越來越差於另一演算法。這其實就是事前估算方法的理論依據,通過演算法時間複雜度來估算演算法時間效率。
演算法時間複雜度
演算法時間複雜度定義:在進行演算法分析時,語句總的執行次數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(n),o(1),o(n的二次方)。我們分別給它們取了非官方的名稱,o(1)叫做常數階、o(n)叫做線性階、n(n的二次方)叫平方階。當然,還有一些其他的。
《大話資料結構》
常見的時間複雜度 常見的時間複雜度如下圖所示 常用的時間複雜度所耗費的時間從小到大依次是 o 1 o logn o n o nlogn o n o n 三次方 o 2 n次方 o n!o n n次方 我們前面已經談到了 o 1 常數階 o logn 對數階 o n 線性階 o n 平方階等,至於o ...
《大話資料結構》
線性表 線性表,從某種就能感覺到,是具有像線一樣的性質的表。在廣場上,有很多人分散在各處,當中有些是小朋友,可也有很多大人,甚至還有不少寵物,這些小朋友的資料對整個廣場人群來說,不能算是線性表的結果。但像剛才提到的那樣,乙個班級的小朋友,乙個跟著乙個排著隊,有乙個打頭,有乙個收尾,當中的小朋友,每乙...
《大話資料結構》
順序儲存方式 線性表的順序儲存結構,說白了,就和剛才的例子一樣,就是在記憶體中找了塊地兒,通過佔位的形式,把一定記憶體空間給佔了,然後把相同資料型別的資料元素依次存放在這塊空地中。既然線性表的每個資料元素的型別都相同,所以可以用c語言 其他語言也相同 的一維陣列來實現順序儲存結構,即把第乙個資料元素...