1. 程式人生 > >【昊昊帶你學】演算法概述

【昊昊帶你學】演算法概述

什麼是演算法

        雖然這篇題目叫概述,不過本菜只是不知道該叫什麼好,我這種小白腫麼敢概述演算法是不。就是總體上說說我對演算法的理解吧 O_o

        演算法可能有些初學童鞋接觸過。有些地方高中教材裡會涉及到(江蘇是有的)。《演算法導論》給出了一個定義:

        所謂演算法就是定義良好的計算過程,它取一個或一組值作為輸入,併產生出一個                    或一組值作為輸出。亦即,演算法就是一系列的計算步驟,用來將輸入資料轉換成輸出結果。

 除此之外,《演算法導論》又說

       可將演算法看作一種工具,用來解決一個具有良好規格說明的計算問題。有關該問題的表述可以用通用的語言,來規定所需的輸入/輸出關係。與之對應的演算法則描述了一個特定的計算過程,用於實現這一輸入/輸出關係。

         看起來有點抽象是伐~那我們來舉個栗子。咱們打牌的時候會有這樣的一種理牌方式,把所有牌從小到大排列(神理牌的高手奏凱!!)。一副牌,兩副牌……估計多少副牌大家都能夠理出來。那我們來分析一下這個例子跟演算法有毛線關係。我們對照《導論》第一個說法來看:

        良好的計算過程就是咱們摸到牌之後把牌放到正確位置的過程(比如這麼說:第一步摸牌,第二步從小到大依次看牌,找到一個位置滿足左邊的牌小於等於剛摸到的牌,同時右邊的牌大於等於剛摸到的牌,第三步:猛插進去!),我們的取值是——數量不限的撲克,而產生的輸出則是——排序好的一把牌(我湊!王炸!)。

而對照第二個說法再看:

        良好規格說明的計算問題顯然就是要把牌從小到大排好(當然這個描述很不嚴謹,時間關係大家明白就好),剛剛的說明規定了輸入和輸出的關係。而上面設計好的演算法則可以實現這個過程。

演算法評價

        那我們就應該有一個疑問,怎麼去評判演算法呢?一般要看幾個方面:演算法正確性、算法佔用的時空資源。

        演算法的正確性顧名思義,對於所有的資料輸入,都能在有限步之內得到完全正確的輸出。也就是說,一個錯誤演算法,可能在某些輸入是根本不會停止,也可能給出的輸出並不是正確的輸出。不過對於一些難問題(NP 、NP完全)來說,我們不一定只採取正確演算法,如果有些演算法的錯誤率可以得到很好的控制,我們也是可以在實際應用的時候採用的。

        算法佔用的資源分為兩類,一是時間,二是空間。前者我們認為是考慮演算法的效率當然簡單的演算法我們可以很清地預測演算法的每一步從而算出時間,不過,有的時候非常複雜的演算法你可能不能很精確地算出時間(或者說演算法需要的步數),不過我們可以用一些數學工具來計算,這個計算方法我就不在這講了,昊昊自己對這個也只能說是瞭解了原理,具體判斷還是靠背各種演算法的效率。至於佔用的空間,應該很好理解,不過我至今還木有考慮過空間T T,真是不合格的程式猿……

資料結構

在這說演算法,不得不提到資料結構。演算法+資料結構=程式。Pascal之父 Nicklaus Wirth就因為這一句話獲得了圖靈獎。由此可見演算法跟資料結構的緊密聯絡。不同的演算法要有適合的資料結構配合才能發揮最佳的效能。而我們常見的資料結構有:棧、佇列、連結串列、散列表、樹、圖、bla bla~~~作為一枚程式猿我們必須掌握普通資料結構各個細節,瞭解它們的特性,以便在我們實際應用的時候靈活地選擇。

先拿棧和佇列對比一下。

棧:先進後出。佇列:先進先出。這兩個比較類似,我舉個栗子。比如羽毛球筒,它就可以看作一個佇列。用完的球從筒屁股那塞進去,而要用的時候從前面取(請大家嫑邪惡 ¯﹃¯)。也就是最先放進去的球最先被取出。而如果哪天發現一端壞掉了,只能從另一端取球,放球(雖然羽毛球不能這樣,但這只是個栗子,栗子。。。。),大家可以想象,最後一次放進去的球在下一次取球時會被第一次取出來。

根據這些不同,我們在程式設計的時候,有時會選擇棧,有時會選擇佇列。以後再細說~

說在最後:

第一篇的內容屬於概括性的描述,是讓大家能夠了解演算法是什麼,演算法怎樣判斷好壞,以及與演算法息息相關的資料結構。這部分並不是毫無作用,隨著大家學習的深入,會逐步體會到的,只可意會不可言傳哈~碼字不容易~