定義:由若干條指令組成的有窮序列,且知足:輸出輸入,肯定性,有限性
輸入:有零個或多個由外部提供的量做爲算法的輸入
輸出:算法產生至少一個量做爲算法的輸出
肯定性:組成算法的每條指令是清晰的,無歧義的
有限性:執行每條指令的時間是有限的,執行的次數也是有限的java
D.E.Knuth(高德納)在他的專著程序的設計的藝術中給出了一個算法的定義是目前學術界比較承認的,
定義以下:算法是定義一個可終止的有序的,無歧義的,可執行的步驟的集合程序員
要成爲金字塔頂的程序員,算法是咱們取經之路上必不可少的,讓咱們一塊兒打開算法的大門,
互相監督,共同進步,我將會在個人我的博客更新個人算法系列文章。算法
算法是計算機科學的核心,是指解決問題的結構化流程,是編排計算機指令的策略性步驟,算法是與語言無關的。即算法不依賴於什麼樣的程序設計方法,更不依賴於具體的編程語言
算法:一種語言
程序:一種文本
算法:受專利法保護
程序:受著做法保護編程
我也會逐一學習這些算法,共勉編程語言
咱們既然要學算法,那麼天然要學怎麼判斷一個算法的高效性,即什麼算法能讓咱們的程序跑的更快,佔用的內存更小。這就要學習算法的複雜度模型函數
複雜性的問題規模N,輸入I和算法A的函數
T=T(N,I,A)
問題規模N沒有明確的單位。T也沒有明確的單位,一個輸入I對應一個問題的實例
判斷一個算法的高效與否不能僅僅看一個算法運行速度的快慢,還要看看一個算法佔用內存的多少,這就有了時間複雜度與空間複雜度工具
我先來說講沒有學習計算算法的複雜度以前,我是怎麼來判斷一個算法的高效與否的,我相信這也是大多數人的錯誤
我當初認爲評價一個算法的執行效率無非就是給出一組數據,用不一樣的算法進行運算,這種方法也叫過後統計法,可是這種方法是有很明顯的缺點的學習
1.執行時間嚴重依賴硬件以及運行時各類不肯定的環境因素
2.必須編寫相應的測試代碼,比較麻煩
3.測試數據的選擇比較難保證公平公正,這句話的意思就是可能不一樣算法對不一樣數據的處理效率不
好比有兩個算法,兩組數據,當輸入數據1的時候算法1的效率更高,當輸入數據2的時候算法二的效率跟高測試
咱們通常使用如下緯度來評估算法的優劣:正確性,健壯性,可讀性
時間複雜度:估算程序指令的執行次數
空間複雜度:估計所須要佔用的內存設計
複雜性是問題規模N,輸入I,和算法A的函數
T=T(N,I,A)
問題規模N沒有明確的單位
T也沒有明確的單位
一個輸入I對應一個問題實例
對特定的算法咱們能夠把A省略,獲得T=T(A,I);
計算機有k種運算O1,O2……Ok。各有其執行的時間ti;
針對具體問題只取主要的運算Om爲度量單位
例如:只涉及四則運算,取乘除問題爲主要運算,對排序問題,取比較操做爲主要運算
最壞狀況Tmax= Tmax (N)=max[I]{T(N,I)}
最好狀況Tmin = Tmin (N)= min[I]{T(N,I)}
平均狀況Tavg = Tavg (N)= average[I]{T(N,I)}
各自的優勢
最經常使用的是最壞狀況時間複雜性
複雜性的漸進形態
進一步忽略係數的漸進性形態---------階,階有四種,上界階,大O
定義
例如T(n)=2n-2k-1,其漸進形態爲2n,省去係數後,其上界階O(n)
下界階,Ω
同級階,θ
無窮小階,小o
通常使用大O表示法來描述複雜,他表示數據規模n對應的複雜度,忽略常數,係數,低階
9 >> O(1) 2n+3 >> O(n) n^2 +2n+6 >> O(n ^2) n^3 + 3n ^2 +2n+6 >> O(n ^3)
大O表示法僅僅是一種粗略的分析模型,是一種估算,幫助咱們短期內瞭解一個算法的執行效率
對階數的細節
對階數通常省略底數
(圖片來源小碼哥)
爲了讓你們更直觀的對比複雜度的大小我使用一個函數生成對比工具
(圖片來源小碼哥)
數據規模較小時
數據規模較大時