算法和算法評價

算法的基本概念

算法:對特定問題求解步驟的一種描述,它是指令的有限序列,其中的每條指令表示一個或多個操做。算法

根據以上定義,能夠知道,算法必定是能夠解決特定問題的,其次,它是有限的,而後,每個指令都表示特定的操做。因而能夠知道算法的五個特性:學習

  • 有窮性:一個算法必須在執行有窮步以後結束,且每一步都必須在有窮時間內完成。若是有相似無限循環的語句,那麼就不能稱之爲算法。
  • 可行性:一個算法是可行的,即算法中描述的操做都是能夠經過已經實現的基本運算執行有限次來實現的。每一步操做都是能夠實現的才能稱之爲算法。
  • 肯定性:算法中每條指令、每條語句必須有確切的含義,相同的輸入必須得出到相同的輸出,不能產生二義性。
  • 輸入:一個算法必須有零個或多個輸入。
  • 輸出:一個算法必須有一個或多個輸出。

算法爲何是有窮的?在操做系統中使用了不少無窮的代碼語句,它們也是很是有用的,它們不是算法,那它們又是什麼?對此,引入一個程序的概念,什麼是算法,什麼又是程序操作系統

根據上面的算法的定義,能夠知道,算法是解決問題的一種方法或一個過程,例如如何將輸入轉換成輸出。一個問題能夠有不少不一樣的算法。而程序是某種程序設計語言對算法的具體實現。咱們能夠用 C 語言來編寫,也能夠用 Python 語言來編寫,只要是在計算機內部運行的程序設計語言均可以。這是對算法和程序的簡單描述。咱們發現,算法更像一個解決問題的 「指導者」,而程序更像一個具體實現的 「實施者」,能夠利用算法來指導程序的編寫和實施。設計

算法和程序主要有三方面的區別:code

  • 有窮性:算法必須是有窮的,程序能夠是無窮的,因此在操做系統中,那些頗有用的,但又無限循環的,能夠 稱之爲程序。
  • 正確性:算法必須是正確的,程序能夠是錯誤的。設計出的算法必須正確的來解決問題,而程序能夠編寫錯誤而後進行修改。
  • 描述方法:算法能夠用僞代碼、程序語言、天然語言、程序框圖等描述,程序只能用程序設計語言編寫並能夠運行。

算法效率的度量

如何設計一個 "好" 的算法?blog

首先一個好的算法必須具備正確性,應該可以正確的解決問題。算法是一個 「指揮者」,若是一個 「指揮者」 不能正確的指導 「實施者」 去實施,那麼它必定不是一個好的算法。程序設計

第二個是可讀性。算法應具備良好的可讀性,以幫助人們理解。在人們修改閱讀算法時,人們應可以快速的理解掌握該算法。class

第三個是健壯性。健壯性是指在輸入非法數據時,算法能適應的作出反應或進行處理。效率

最後一個是效率與存儲量需求。效率是指算法執行時間,存儲量需求是指算法執行過程當中所需最大存儲空間。這是最經常使用的用來考量一個好的算法的標準。也就是時間複雜度空間複雜度變量

時間複雜度

在學習時間複雜度以前,先掌握兩個概念:語句的頻度T(n)

語句頻度:該條語句可能重複執行的次數

T(n):全部語句的頻度之和,其中 n 爲問題的規模

int sum = 0;
for(int i=1; i<=n; i++)
    sum += i;

第一句是初始化 sum 爲 0,它的語句頻度是 1,由於它只被執行了一次。第二個是循環體中的語句 sum += i ,根據它的判斷條件,能夠知道它執行了 n 次,因此該條語句的語句頻度是 n。那麼該段代碼的語句頻度之和就是 T(n)=1+n

時間複雜度:記做 T(n) = O(f(n)) ,其中 O 表示 T(n)f(n) 在 n 趨向於正無窮時爲同階無窮大,能夠把 f(n) 理解爲某一個數量級或者是當 n 趨於正無窮時的一種增加率。

根據同階無窮大的知識,能夠知道:

因此說,它的 f(n)=n ,它的時間複雜度爲 O(n)

時間複雜度有三種分類:最壞時間複雜度、最好時間複雜度、平均時間複雜度

int sum = 0;
if(n != 0)
    for(int i=1; i<=n; i++)
        sum += i;

這段代碼中,若是 n 不等於 0 ,它的 T(n) = 1 + n,它的時間複雜度爲 O(n) ,若是當 n 等於 0 ,它僅僅執行了第一條語句,也就是說它的 T(n) = 1,則它的時間複雜度爲 O(1) 。因此說在不一樣的判斷中,時間複雜度是不一樣的,因此有最壞和最好之分,平均時間複雜度就是在全部輸入的機率的狀況下,求一個時間複雜度的指望值。

在分析一個算法時, 每每會使用最壞時間複雜度,這個是最具備實際意義的。

學習了時間複雜度的分類後,來看一下時間複雜度在運算上有怎樣的規則。

加法規則:當對兩個時間複雜度進行求和運算時,能夠將較大數量級的代碼的時間複雜度做爲它們的和,能夠經過同階無窮大來進行驗證

乘法規則:兩個時間複雜度的乘積可使它先對數量級進行乘積再求同階無窮大

一般採用基本運算頻度來分析算法時間複雜度,基本運算頻度也就是指最深層的循環語句的頻度。

int sum = 0;
for(int i=1; i<=n; i++)
    sum += i;
for(int i=1; i<=n; i++)
    for(int j=1; j<=n; i++)
        sum += i;

這段代碼中,第一句的語句頻度是 1,而後第三句循環執行 n 次,語句頻度是 n,第四句第五句是一個雙層循環,而且都是循環 n 次,所以它的語句頻度是 n2 ,因此這段代碼的 T(n) = 1 + n + n2 。根據加法規則,它的時間複雜度是 O(n2) 。它的最深層的循環語句的時間複雜度爲 O(n2) ,採用基本運算頻度來分析算法時間複雜度,也能夠得出它的時間複雜度是 O(n2) 。

常見時間複雜度

空間複雜度

算法的空間複雜度是指算法消耗的存儲空間,記做 S(n) = O(g(n)) ,O 表示同階無窮大,g(n) 表示數量級,n 表明問題規模。

在計算算法空間複雜度時,要注意一點,就是什麼是消耗的存儲空間,它是除自己所用的指令、常數、變量和輸入數據外的輔助空間。

算法原地工做時指算法所需輔助空間爲常量,記做 O(1)

總結

相關文章
相關標籤/搜索