算法概念 及 複雜度

 

1、算法:

 算法是對特定問題求解步驟的一種描述,是獨立存在的一種解決問題的方法和思想。它是指令的有限序列,其中每一條指令表示一個或多個操做;
此外,成爲一個算法須要知足如下條件或特性:算法

(1)有窮性。一個算法必須老是在執行有窮步以後結束,且每一步均可在有窮時間內完成。
(2)肯定性。算法中每一條指令必須有確切的含義讀者理解時不會產生二義性。而且,在任何條件下,算法只有惟一的一條執行路徑,即對於相同的輸入只能得出相同的輸出。
(3)可行性。一個算法是能行的,即算法中描述的操做都是能夠經過已經實現的基本運算執行有限次來實現的。
(4)輸入。零個或多個的輸入。
(5)輸出。一個或多個的輸出。數組

2、算法設計的要求

一般設計一個「好」的算法應考慮達到如下目標:函數

(1)正確性。對於合法輸入可以獲得知足的結果;算法可以處理非法處理,並獲得合理結果;算法對於邊界數據和壓力數據都能獲得知足的結果。性能

(2)可讀性。算法要方便閱讀,理解和交流,只有本身能看得懂,其它人都看不懂,談和好算法。測試

(3)健壯性。算法不該該產生莫名其妙的結果,一下子正確,一下子又是其它結果。spa

(4)高性價比,效率與低存儲量需求。利用最少的時間和資源獲得知足要求的結果,能夠經過(時間複雜度和空間複雜度來斷定)

  同一問題可用不一樣算法解決,而一個算法的質量優劣將影響到算法乃至程序的效率。算法分析的目的在於選擇合適算法和改進算法。
  計算機科學中,算法的時間複雜度是一個函數,它定量描述了該算法的運行時間。這是一個關於表明算法輸入值的字符串的長度的函數。時間複雜度經常使用大O符號【O】表述,不包括這個函數的低階項和首項係數。使用這種方式時,時間複雜度可被稱爲是漸近的,它考察當輸入值大小趨近無窮時的狀況。
  算法複雜度分爲時間複雜度和空間複雜度。其做用:時間複雜度是指執行算法所須要的計算工做量;而空間複雜度是指執行這個算法所須要的內存空間。(算法的複雜性體如今運行該算法時的計算機所需資源的多少上,計算機資源最重要的是時間和空間(即寄存器)資源,所以複雜度分爲時間和空間複雜度)。設計

一、時間複雜度

(1)時間頻度 指針

   一個算法執行所耗費的時間,從理論上是不能算出來的,必須上機運行測試才能知道,但咱們不可能也沒有必要對每一個算法都上機測試,只需知道哪一個算法花費的時間多,哪一個算法花費的時間少就能夠了。而且一個算法花費的時間與算法中語句的執行次數成正比例,哪一個算法中語句執行次數多,它花費時間就多。一個算法中的語句執行次數稱爲語句頻度或時間頻度,記爲T(n)。(算法中的基本操做通常指算法中最深層循環內的語句)對象

(2)時間複雜度  blog

   在剛纔提到的時間頻度中,n稱爲問題的規模,當n不斷變化時,時間頻度T(n)也會不斷變化。但有時咱們想知道它變化時呈現什麼規律。爲此,咱們引入時間複雜度的概念。

  通常狀況下,算法中基本操做重複執行的次數是問題規模n的某個函數,用T(n)表示,如有某個輔助函數f(n), 使得當n趨近於無窮大時,T(n)/f(n)的極限值爲不等於零的常數,則稱f(n)是T(n)的同數量級函數。記做T(n)=O(f(n)), 稱O(f(n))爲算法的漸進時間複雜度 ,簡稱時間複雜度。O是數量級的符號。

  在各類不一樣算法中,若算法中語句執行次數爲一個常數,則時間複雜度爲O(1)。另外,在時間頻度不相同時,時間複雜度有可能相同,如T(n)=n2+3n+4與T(n)=4n2+2n+1它們的頻度不一樣,但時間複雜度相同,都爲O(n2)。

(3)最壞時間複雜度和平均時間複雜度 

      最壞狀況下的時間複雜度稱最壞時間複雜度。通常不特別說明,討論的時間複雜度均是最壞狀況下的時間複雜度。 這樣作的緣由是:最壞狀況下的時間複雜度是算法在任何輸入實例上運行時間的上界,分析最壞的狀況以估算算法指向時間的一個上界。這就保證了算法的運行時間不會比任何更長。
  在最壞狀況下的時間複雜度爲T(n)=0(n),它表示對於任何輸入實例,該算法的運行時間不可能大於0(n)。 平均時間複雜度是指全部可能的輸入實例均以等機率出現的狀況下,算法的指望運行時間。
  指數階0(2n),顯然,時間複雜度爲指數階0(2n)的算法效率極低,當n值稍大時就沒法應用。

按數量級遞增排列,常見的時間複雜度有:

常數階 對數階 線性階 線性對數階 平方階 立方階 …… K次方階 指數階
O(1) O(log2 n ) O(n) O(nlog2 n) O(n2 ) O(n3 )   O(nk ) O(2n )

       

 

複雜度低 ---->---->---->---->---->---->---->---->---->---->---->---->----> 複雜度高 

隨着問題規模n的不斷增大,上述時間複雜度不斷增大,算法的執行效率越低。

時間複雜度的分析方法:
  一、時間複雜度就是函數中基本操做所執行的次數
  二、通常默認的是最壞時間複雜度,即分析最壞狀況下所能執行的次數
  三、忽略掉常數項
  四、關注運行時間的增加趨勢,關注函數式中增加最快的表達式,忽略係數
  五、計算時間複雜度是估算隨着n的增加函數執行次數的增加趨勢
  六、遞歸算法的時間複雜度爲:遞歸總次數 * 每次遞歸中基本操做所執行的次數

計算方法
  1.通常狀況下,算法中基本操做重複執行的次數是問題規模n的某個函數,用T(n)表示,如有某個輔助函數f(n),使得當n趨近於無窮大時,T(n)/f(n)的極限值爲不等於零的常數,則稱f(n)是T(n)的同數量級函數。記做T(n)=O(f(n)),稱O(f(n)) 爲算法的漸進時間複雜度,簡稱時間複雜度。
  分析:隨着模塊n的增大,算法執行的時間的增加率和 f(n) 的增加率成正比,因此 f(n) 越小,算法的時間複雜度越低,算法的效率越高。
  2. 在計算時間複雜度的時候,先找出算法的基本操做,而後根據相應的各語句肯定它的執行次數,再找出 T(n) 的同數量級(它的同數量級有如下:1,log2n,n,n log2n ,n的平方,n的三次方,2的n次方,n!),找出後,f(n) = 該數量級,若 T(n)/f(n) 求極限可獲得一常數c,則時間複雜度T(n) = O(f(n))
  則有 T(n) = n 的平方+n的三次方,根據上面括號裏的同數量級,咱們能夠肯定 n的三次方 爲T(n)的同數量級
  則有 f(n) = n的三次方,而後根據 T(n)/f(n) 求極限可獲得常數c
  則該算法的時間複雜度:T(n) = O(n^3) 注:n^3便是n的3次方。

  3.時間複雜度比較簡單的計算方法是:看看有幾重for循環,只有一重則時間複雜度爲O(n),二重則爲O(n^2),以此類推,若是有二分則爲O(logn),二分例如快速冪,二分查找,若是一個for循環套一個二分,那麼時間複雜度則爲O(logn)。

二、空間複雜度:

  算法的空間複雜度並非計算實際佔用的空間,而是計算整個算法的輔助空間單元的個數,與問題的規模沒有關係。算法的空間複雜度S(n)定義爲該算法所耗費空間的數量級。
S(n)=O(f(n)) 若算法執行時所須要的輔助空間相對於輸入數據量n而言是一個常數,則稱這個算法的輔助空間爲O(1); 
遞歸算法的空間複雜度:遞歸深度N*每次遞歸所要的輔助空間, 若是每次遞歸所需的輔助空間是常數,則遞歸的空間複雜度是 O(N).

空間複雜度的分析方法:

 一個算法的空間複雜度S(n)定義爲該算法所耗費的存儲空間,它也是問題規模n的函數。空間複雜度是對一個算法在運行過程當中臨時佔用存儲空間大小的量度。

  一個算法在計算機存儲器上所佔用的存儲空間,包括存儲算法自己所佔用的存儲空間,算法的輸入輸出數據所佔用的存儲空間和算法在運行過程當中臨時佔用的存儲空間這三個方面。

  一個算法的空間複雜度只考慮在運行過程當中爲局部變量分配的存儲空間的大小,它包括爲參數表中形參變量分配的存儲空間和爲在函數體中定義的局部變量分配的存儲空間兩個部分。

  算法的空間複雜度通常也以數量級的形式給出。如當一個算法的空間複雜度爲一個常量,即不隨被處理數據量n的大小而改變時,可表示爲O(1);當一個算法的空間複雜度與以2爲底的n的對數成正比時,可表示爲O(log2n);當一個算法的空間複雜度與n成線性比例關係時,可表示爲O(n)。若形參爲數組,則只須要爲它分配一個存儲由實參傳送來的一個地址指針的空間,即一個機器字長空間;若形參爲引用方式,則也只須要爲其分配存儲一個地址的空間,用它來存儲對應實參變量的地址,以便由系統自動引用實參變量。

空間複雜度補充:

  一個程序的空間複雜度是指運行完一個程序所需內存的大小。利用程序的空間複雜度,能夠對程序的運行所須要的內存多少有個預先估計。一個程序執行時除了須要存儲空間和存儲自己所使用的指令、常數、變量和輸入數據外,還須要一些對數據進行操做的工做單元和存儲一些爲現實計算所需信息的輔助空間。程序執行時所需存儲空間包括如下兩部分。  
  (1)固定部分。這部分空間的大小與輸入/輸出的數據的個數多少、數值無關。主要包括指令空間(即代碼空間)、數據空間(常量、簡單變量)等所佔的空間。這部分屬於靜態空間。
  (2)可變空間,這部分空間的主要包括動態分配的空間,以及遞歸棧所需的空間等。這部分的空間大小與算法有關。
  一個算法所需的存儲空間用f(n)表示。S(n)=O(f(n))  其中n爲問題的規模,S(n)表示空間複雜度。

時間與空間複雜度比較  

對於一個算法,其時間複雜度和空間複雜度每每是相互影響的。當追求一個較好的時間複雜度時,可能會使空間複雜度的性能變差,便可能致使佔用較多的存儲空間;反之,當追求一個較好的空間複雜度時,可能會使時間複雜度的性能變差,便可能致使佔用較長的運行時間。

  另外,算法的全部性能之間都存在着或多或少的相互影響。所以,當設計一個算法(特別是大型算法)時,要綜合考慮算法的各項性能,算法的使用頻率,算法處理的數據量的大小,算法描述語言的特性,算法運行的機器系統環境等各方面因素,纔可以設計出比較好的算法。算法的時間複雜度和空間複雜度合稱爲算法的複雜度。

經常使用的算法的時間複雜度和空間複雜度:

排序法 平均時間 最差情形 穩定度 額外空間 備註
冒泡 O(n2 ) O(n2 ) 穩定 O(1) n較小時較好
交換 O(n2 ) O(n2 ) 不穩定 O(1) n較小時較好
選擇 O(n2 ) O(n2 ) 不穩定 O(1) n較小時較好
插入 O(n2 ) O(n2 ) 穩定 O(1) 大部分已排序時較好
基數 O(logR B) O(logR B) 穩定 O(n)

B是真數(0-9),

R是基數(個十百)

Shell O(nlogn) O(ns ) 1<s<2 不穩定 O(1)

s是所選分組

快速 O(nlogn) O(n2 ) 不穩定 O(nlogn) n較大時較好
歸併 O(nlogn) O(nlogn) 穩定 O(1) n較大時較好
O(nlogn) O(nlogn) 不穩定 O(1)

n較大時較好

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 穩定的排序:保證,排序關鍵字相同的狀況下,對象的相對位置不變

相關文章
相關標籤/搜索