前言: 學習這東西,很枯燥也很煩,參考許多博文,選了許多。結合一些東西,記錄一下, 也是為了以後回顧學習。
演算法效率:
說到演算法效率 , 不得不提兩個指標,那就是
時間複雜度
空間複雜度
好的演算法應該具備時間效率高和儲存量低的特點。
計算機能快速完成大量複雜的資料處理,但是要完成這個工作,計算機也是需要一定的資源的。得根據資料大小和演算法來消使用處理器資源。要想程式能夠高效的執行,就要考慮到演算法的效率問題了。演算法效率的評估, 怎麼評估呢,那就是這兩個指標了。
時間複雜度:評估執行程式所需的時間。可以估算出程式對處理器的使用程度。
空間複雜度:評估執行程式所需的儲存空間。可以估算出程式對計算機記憶體的使用程度。
我們在設計演算法的時候。一般是先考慮系統環境,在考慮時間複雜度和空間複雜度, 中間取乙個合適的點,通常時間複雜度要比空間複雜度更容易產生問題,所以我們大多主要研究時間複雜度。
時間頻度
乙個演算法執行所消耗的時間,理論上是不能推論出來的,必須經過機器測試才知道。但是我們也不可能也沒有必要對每個演算法逐個進行上機測試,只需要知道演算法花費的時間就可以了。演算法花費的時間與演算法中語句的執行次數成正比例,哪個演算法中語句執行次數多,它花費時間就多。乙個演算法中的語句執行次數稱為語句頻度或時間頻度。記為t(n)。
時間複雜度
時間頻度t(n) 。 n 為問題的規模,當n不斷的變化時,時間頻度t(n) 也會隨之不斷的變化。有時候我們想知道它的變化呈現出什麼規律,所以 有了時間複雜度的概念。
演算法中 基本操作重複執行的次數,是問題規模 n 的某個函式 用 t(n) 表示。 如果有某個輔助函式 f (n), 當n趨近於無窮大的時候,t(n) / f(n) 的極限值為不等於0 的常數。則 f (n) 為t(n) 的同數量級函式,表示為 t(n)=o(f(n)) 它稱為演算法的漸進時間複雜度,簡稱時間複雜度。
大o表示法
上面用o( ) 來表示演算法時間複雜度的記法,稱之為大o 表示法。
評估乙個演算法我們可以從三個角度來評估: 分別為最理想情況,最壞情況,和平均情況。 從測試結果來看, 平均情況大多和最壞結果持平,而且評估最壞情況也可以避免後面出現的糟糕情況。所以一般情況下,我們設計演算法時都要直接估算最壞情況的複雜度。
大o表示法o(f(n)中的f(n)的值可以為1、n、logn、n²等,因此我們可以將o(1)、o(n)、o(logn)、o(n²)分別可以稱為常數階、線性階、對數階和平方階,那麼如何推導出f(n)的值呢?我們接著來看推導大o階的方法。
推導大o階
推導大o階,我們可以按照如下的規則來進行推導,得到的結果就是大o表示法:
1.用常數1來取代執行時間中所有加法常數。
2.修改後的執行次數函式中,只保留最高端項
3.如果最高端項存在且不是1,則去除與這個項相乘的常數。
常數階:
int m= 0 ;n = 100 //上面演算法的執行次數的函式為 f(n) = 3,根據推導大o階的規則1,我們常數3改為1,則這個演算法的時間複雜度為o(1)。如果 m = (1+n)*n/2這條語句再執行10遍,因為這與問題大小n的值並沒有關係,所以這個演算法的時間複雜度仍舊是o(1),我們可以稱之為常數階。執行一次
m = (1+n)*n/2 ; //
執行一次
system.out.prntln(m)//
執行一次
線性階:
線性階主要分析迴圈結構的運**況。
for(int i=0;i)迴圈體中的**執行了n次,因此時間複雜度為o(n)。
對數階 :
int number=1;內層迴圈的時間複雜度在講到線性階時就已經得知是o(n),現在經過外層迴圈n次,那麼這段演算法的時間複雜度則為o(n²)。while(number
number每次乘以2後,都會越來越接近n,當number不小於n時就會退出迴圈。假設迴圈的次數為x,則由2^x=n得出x=log₂n,因此得出這個演算法的時間複雜度為o(logn)。
平方階:
下面是迴圈巢狀
for(int i=0;i)
其他常見複雜度
除了常數階、線性階、平方階、對數階,還有如下時間複雜度:
f(n)=nlogn時,時間複雜度為o(nlogn),可以稱為nlogn階。
f(n)=n³時,時間複雜度為o(n³),可以稱為立方階。
f(n)=2ⁿ時,時間複雜度為o(2ⁿ),可以稱為指數階。
f(n)=n!時,時間複雜度為o(n!),可以稱為階乘階。
f(n)=(√n時,時間複雜度為o(√n),可以稱為平方根階。
演算法中常見的f(n)值根據幾種典型的數量級複雜度比較
o(n)、o(logn)、o(√n )、o(nlogn )隨著n的增加,複雜度提公升不大,因此這些複雜度屬於效率高的演算法,反觀o(2ⁿ)和o(n!)當n增加到50時,複雜度就突破十位數了,這種效率極差的複雜度最好不要出現在程式中,因此在動手程式設計時要評估所寫演算法的最壞情況的複雜度。
更直觀的圖:
t(n)值隨著n的值的變化而變化,其中可以看出o(n!)和o(2ⁿ)隨著n值的增大,它們的t(n)值上公升幅度非常大,而o(logn)、o(n)、o(nlogn)隨著n值的增大,t(n)值上公升幅度則很小。
常用的時間複雜度按照耗費的時間從小到大依次是:
o(1)
演算法之 時間複雜度和空間複雜度
平時用的少,經常忘記,這裡記錄下時間複雜度的概念 複雜度是演算法的一種標記方法。用o表示,通常讀為big o o的包含了時間複雜和空間複雜度 這裡就只說時間複雜度。時間複雜度的概念,個人總結,可能不太準確。時間複雜度,即標記乙個問題,隨著問題規模的變化,所需要花費時間的關係。時間複雜度就是問題規模和...
演算法分析之 時間複雜度
當電腦執行下面這段 的時候,執行任何一條語句都需要花費時間 為了方便討論,這裡我們把每一條語句的執行時間都看做是一樣的,記為乙個時間單元 這個程式有這麼幾個地方消耗了時間 藍色框的兩條語句,花費2個時間單元 黑色框的一條語句,花費n 1個時間單元 紅色框的兩條語句,花費2 n個時間單元 那麼一共花費...
演算法之時間複雜度簡析
最近準備對演算法進行一些系統的總結和學習,不積跬步無以至千里,不積小流無以成江海.此文主要對時間複雜度進行簡單梳理和個人總結,本人才疏學淺,有所疏漏在所難免,如有不當和錯誤之處,歡迎指正 時間複雜度,用簡單地話描述為 為了大概估算程式運算時間的一種概量。那用什麼來估算的呢?用簡單的程式執行 的次數,...