算法系列1 初識演算法 演算法複雜性模型 演算法複雜度的計算
阿新 • • 發佈:2020-09-19
## 算法系列1 初識演算法
## 什麼是演算法?
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200919091641177.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3BqaDg4,size_16,color_FFFFFF,t_70#pic_center)定義:由若干條指令組成的有窮序列,且滿足:輸出輸入,確定性,有限性
輸入:有零個或多個由外部提供的量作為演算法的輸入
輸出:演算法產生至少一個量作為演算法的輸出
確定性:組成演算法的每條指令是清晰的,無歧義的
有限性:執行每條指令的時間是有限的,執行的次數也是有限的
D.E.Knuth(高德納)在他的專著程式的設計的藝術中給出了一個演算法的定義是目前學術界比較認可的,
定義如下:演算法是定義一個可終止的有序的,無歧義的,可執行的步驟的集合
**要成為金字塔頂的程式設計師,演算法是我們取經之路上必不可少的,讓我們一起開啟演算法的大門,
互相監督,共同進步,我將會在我的個人部落格更新我的算法系列文章。**
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200919092714965.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3BqaDg4,size_16,color_FFFFFF,t_70#pic_center)
## 演算法與程式的區別
演算法是電腦科學的核心,是指解決問題的結構化流程,是編排計算機指令的策略性步驟,演算法是與語言無關的。即演算法不依賴於什麼樣的程式設計方法,更不依賴於具體的程式語言
演算法:一種語言
程式:一種文字
演算法:受專利法保護
程式:受著作法保護
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200919093142372.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3BqaDg4,size_16,color_FFFFFF,t_70#pic_center)
## 一些演算法的名稱
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200919093623684.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3BqaDg4,size_16,color_FFFFFF,t_70#pic_center)
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200919093636561.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3BqaDg4,size_16,color_FFFFFF,t_70#pic_center)
**我也會逐一學習這些演算法,共勉**
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200919093721538.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3BqaDg4,size_16,color_FFFFFF,t_70#pic_center)
**我們既然要學演算法,那麼自然要學怎麼判斷一個演算法的高效性,即什麼演算法能讓我們的程式跑的更快,佔用的記憶體更小。這就要學習演算法的複雜度模型**
## 演算法的複雜度模型
複雜性的問題規模N,輸入I和演算法A的函式
T=T(N,I,A)
問題規模N沒有明確的單位。T也沒有明確的單位,一個輸入I對應一個問題的例項
**判斷一個演算法的高效與否不能僅僅看一個演算法執行速度的快慢,還要看看一個算法佔用記憶體的多少,這就有了時間複雜度與空間複雜度**
**我先來講講沒有學習計算演算法的複雜度之前,我是怎麼來判斷一個演算法的高效與否的,我相信這也是大多數人的錯誤**
我當初認為評價一個演算法的執行效率無非就是給出一組資料,用不同的演算法進行運算,這種方法也叫事後統計法,但是這種方法是有很明顯的缺點的
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200919101205922.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3BqaDg4,size_16,color_FFFFFF,t_70#pic_center)
## 缺點
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)}
各自的優點
最常用的是最壞情況時間複雜性
## 計算時間複雜度的例子
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/2020091915050451.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3BqaDg4,size_16,color_FFFFFF,t_70#pic_center)
**複雜性的漸進形態**
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/2020091915063773.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3BqaDg4,size_16,color_FFFFFF,t_70#pic_center)
## 演算法複雜性的階
進一步忽略係數的漸進性形態---------階,階有四種,上界階,大O
定義
例如T(n)=2n-2k-1,其漸進形態為2n,省去係數後,其上界階O(n)
下界階,Ω
同級階,θ
無窮小階,小o
## 對階記號的認識
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200919152137312.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3BqaDg4,size_16,color_FFFFFF,t_70#pic_center)
## 大O表示法(Big O)n-1
**一般使用大O表示法來描述複雜,他表示資料規模n對應的複雜度,忽略常數,係數,低階**
```java
9 >> O(1)
2n+3 >> O(n)
n^2 +2n+6 >> O(n ^2)
n^3 + 3n ^2 +2n+6 >> O(n ^3)
```
**大O表示法僅僅是一種粗略的分析模型,是一種估算,幫助我們短時間內瞭解一個演算法的執行效率**
**對階數的細節
對階數一般省略底數**
(圖片來源小碼哥)
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200919104920840.png#pic_center)
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/2020091910493592.png#pic_center)
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200919105002654.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3BqaDg4,size_16,color_FFFFFF,t_70#pic_center)**為了讓大家更直觀的對比複雜度的大小我使用一個函式生成對比工具**
(圖片來源小碼哥)
**資料規模較小時**
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200919105327133.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3BqaDg4,size_16,color_FFFFFF,t_70#pic_center)
**資料規模較大時**
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200919105355788.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3BqaDg4,size_16,color_FFFFFF,t_70#pic_center)
## 以上就是對演算法複雜性計算的一些略微的總結,在後續學習過程中我會不斷完善,歡迎大家關注我和我一同學習,一同進步
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200919152928961.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3BqaDg4,size_16,color_FFFFFF,t_70#pic_center)