當今世界最爲經典的十大算法 博客分類: 經典文章轉載 算法數據結構網絡應用數據挖掘J#

本文轉載自July CSDN博客:http://blog.csdn.net/v_JULY_v/archive/2011/03/07/6228235.aspx

第一部分、來自聖經的十大算法

    當今世界,已經被發現或創造的經典算法數不勝數。如果,一定要投票選出你最看重的十大算法,你會作何選擇列?     曾有人在StackExchange上發起了提問,向網友們徵集當今世界最爲經典的十大算法。衆人在一大堆入圍算法中進行投票,最終得出了票數最高的以下十個算法。

    來自聖經的十大算法:     發起人的描述:《來自聖經的證明》收集了數十個簡潔而優雅的數學證明,迅速贏得了大批數學愛好者的追捧。如果還有一本《來自聖經的算法》,哪些算法會列入 其中呢?現在,朋友們,以下是數十種候選算法,如果你覺得它是當今世界最經典的算法,就請您爲它投一票.....     最終在StackExchange上產生了下面得票數最高的十大經典算法(投票數統計截止到2011年3月7日 ):

第十名:Huffman coding(霍夫曼編碼)     霍夫曼編碼(Huffman Coding)是一種編碼方式,是一種用於無損數據壓縮的熵編碼(權編碼)算法。1952年,David A. Huffman在麻省理工攻讀博士時所發明的,並發表於《一種構建極小多餘編碼的方法》(A Method for the Construction of Minimum-Redundancy Codes)一文。

第九名:Binary Search (二分查找)     在一個有序的集合中查找元素,可以使用二分查找算法,也叫二分搜索。二分查找算法先比較位於集合中間位置的元素與鍵的大小,有三種情況(假設集合是從小到大排列的):     1.鍵小於中間位置的元素,則匹配元素必在左邊(如果有的話),於是對左邊的區域應用二分搜索。     2.鍵等於中間位置的元素,所以元素找到。     3.鍵大於中間位置的元素,則匹配元素必在右邊(如果有的話),於是對右邊的區域應用二分搜索。 另外,當集合爲空,則代表找不到。

第八名:Miller-Rabin作的類似的試驗測試     這個想法是利用素數的性質(如使用費馬大定理)的小概率尋找見證不數素數。如果沒有證據是足夠的隨機檢驗後發現,這一數字爲素數。

第七名:Depth First Search、Breadth First Search (深度、廣度優先搜索)     它們是許多其他算法的基礎。關於深度、廣度優先搜索算法的具體介紹,請參考此文:教你通透徹底理解:BFS和DFS優先搜索算法

第六名:Gentry's Fully Homomorphic Encryption Scheme (紳士完全同態加密機制)算法。     此算法很漂亮,它允許第三方執行任意加密數據運算得不到私鑰(不是很瞭解)。

第五名:Floyd-Warshall all-pairs最短路徑算法     關於此算法的介紹,可參考我寫的此文:幾個最短路徑算法比較(http://blog.csdn.net/v_JULY_v/archive/2011/02/12/6181485.aspx )。 d[]: 二維數組. d[i,j]最小花費、或最短路徑的鄰邊。

for k from 1 to n:   for i from 1 to n:     for j from 1 to n:       d[i,j] = min(d[i,j], d[i,k] + d[k,j])

第四名:Quicksort(快速排序)     快速排序算法幾乎涵蓋了所有經典算法的所有榜單。它曾獲選二十世紀最偉大的十大算法(參考這:細數二十世紀最偉大的10大算法 )。關於快速排序算法的具體介紹,請參考我寫的這篇文章:一之續、快速排序算法的深入分析 ,及十二、一之再續:快速排序算法之所有版本的c/c++實現

第三名:BFPRT 算法     1973 年,Blum、Floyd、Pratt、Rivest、Tarjan集體出動,合寫了一篇題爲 “Time bounds for selection” 的論文,給出了一種在數組中選出第 k 大元素的算法,俗稱"中位數之中位數算法"。依靠一種精心設計的 pivot 選取方法,該算法從理論上保證了最壞情形下的線性時間複雜度,打敗了平均線性、最壞 O(n^2) 複雜度的傳統算法。一羣大牛把遞歸算法的複雜度分析玩弄於骨掌股掌之間,構造出了一個當之無愧的來自聖經的算法。

    我在這裏簡單介紹下在數組中選出第k大元素的時間複雜度爲O(N)的算法:     類似快排中的分割算法:

每次分割後都能返回樞紐點在數組中的位置s,然後比較s與k的大小 若大的話,則再次遞歸劃分array[s..n], 小的話,就遞歸array[left...s-1] //s爲中間樞紐點元素。 否則返回array[s],就是partition中返回的值。 //就是要找到這個s。

找到符合要求的s值後,再遍歷輸出比s小的那一邊的元素。

    各位可參考在:算法導論上,第九章中,以期望線性時間做選擇,一節中, 我找到了這個 尋找數組中第k小的元素的,平均時間複雜度爲O(N)的證明:上述程序的期望運行時間,最後證明可得O(n),且假定元素是不同的。

第二名:Knuth-Morris-Pratt字符串匹配算法     關於此算法的介紹,請參考此文:六、教你從頭到尾徹底理解KMP算 。KMP算法曾經落選於二十世紀最偉大的十大算法,但人們顯然不能接受,如此漂亮、高效的KMP算法竟然會落選。所以,此次最終投票產出生,KMP算法排到了第二名。

第一名:Union-find     嚴格地說,並查集是一種數據結構,它專門用來處理集合的合併操作和查詢操作。並查集巧妙地借用了樹結構,使得編程複雜度降低到了令人難以置信的地步;用上 一些遞歸技巧後,各種操作幾乎都能用兩行代碼搞定。而路徑壓縮的好主意,更是整個數據結構的畫龍點睛之筆。並查集的效率極高,單次操作的時間複雜度幾乎可 以看作是常數級別;但由於數據結構的實際行爲難以預測,精確的時間複雜度分析需要用到不少高深的技巧。並行查找,最終佔據了此份榜單的第一名。

    補充:前三名的投票數,只相差4票,8票。所以這個排名日後還會不斷有所變化。但不管最終結果怎樣,這前十名的算法已經基本敲定了。 原投票網址http://cstheory.stackexchange.com/questions/189/algorithms-from-the-book

第二部分、當今世界最爲經典的十大算法--投票進行時     怎麼樣,上文那些投票產生出來的來自聖經的算法,你是否熟悉?你是否熟悉?或者, 如果要您選出您心目中,當今世界最爲經典的十大算法,您肯定也、絕對不一定認同上述十個所謂來自聖經的算法便是當今世界最爲經典的十大算法,對吧? ok,那麼,現在,我給你一個投票權,你會把票投給哪一個算法列?好的,咱們也來一次投票吧,請把你的意見,決定權寫在本文下面的評論裏。

    我把已經產生的前十名的算法,再寫在下面,方便投票(投票截止日期 :後 年的今天,即二零一三年三月七日 ):

、Huffman coding(霍夫曼編碼)。 、Binary Search (二分查找)。 、Miller-Rabin作的類似的試驗測試。 、Depth First Search(深度優先搜索)。 、紳士完全同態加密機制 、Floyd-Warshall all-pairs最短路徑算法。 、Quicksort(快速排序)。 、BFPRT 算法。 、Knuth-Morris-Pratt字符串匹配算法。 、Union-find。

爲了讓大家有更多的選擇,我再貼出其它幾種同樣經典但暫時未能排進上述榜單前十名的候選算法:

十一、Cooley-Tukey FFT 算法。快速傅里葉變換算法。關於傅里葉變換算法的介紹,請參考此文:十、從頭到尾徹底理解傅里葉變換算法、上 ,及十、從頭到尾徹底理解傅里葉變換算法、下

十二linear programming ,線性規劃。 十三Dijkstra 算法。與上第五一樣,又一種最短路徑算法。具體介紹,請參考:二之續、徹底理解Dijkstra算法 ,和二(再續)、Dijkstra 算法+fibonacci堆的逐步c實現

十四Merge Sort 。歸併排序。 十五Ford–Fulkerson 算法。網絡最大流算法。 十六輾轉相除法 。       在數學中,輾轉相除法,又稱歐幾里得算法,是求最大公約數的算法,即求兩個正整數之最大公因子的算法。此算法作爲TAOCP第一個算法被闡述,足見此算法 被重視的程度。它是已知最古老的算法, 其可追溯至3000年前。輾轉相除法首次出現於歐幾里得的《幾何原本》(第VII卷,命題i和ii)中,而在中國則可以追溯至東漢出現的《九章算術》。擴 展的輾轉相除法則構造性地證明了,對任意整數a和b ,存在一對x、y使得 ax + by = gcd(a, b) 。

十七RSA加密演算法 。一種加密算法,日後再做詳細介紹。 十八遺傳算法 。可參考本人寫的關於GA 算法的這篇文章:七、遺傳算法 透析GA本質

十九最大期望(EM)算法 。     此算法入選數據挖掘領域十大經典算法 。 在統計計算中,最大期望(EM)算法是在概率(probabilistic)模型中尋找參數最大似然估計的算法,其中概率模型依賴於無法觀測的隱藏變量 (Latent Variable)。最大期望經常用在機器學習和計算機視覺的數據聚類(Data Clustering)領域。最大期望算法經過兩個步驟交替進行計算,第一步是計算期望(E),利用對隱藏變量的現有估計值,計算其最大似然估計值;第二 步是最大化(M),最大化在 E 步上求得的最大似然值來計算參數的值。M 步上找到的參數估計值被用於下一個 E 步計算中,這個過程不斷交替進行。

二十、數據壓縮     數據壓縮是通過減少計算機中所存儲數據或者通信傳播中數據的冗餘度,達到增大數據密度,最終使數據的存儲空間減少的技術。數據壓縮在文件存儲和分佈式系統領域有着十分廣泛的應用。數據壓縮也代表着尺寸媒介容量的增大和網絡帶寬的擴展。

二十一、Hash函數     Hash,一般翻譯做“散列”,也有直接音譯爲“哈希”的,就是把任意長度的輸入(又叫做預映射, pre-image),通過散列算法,變換成固定長度的輸出,該輸出就是散列值。關於hash表的詳細闡述,請參考此篇文章:十一、從頭到尾徹底解析Hash表 算法

二十二、Dynamic Programming (動態規劃)。關於動態規劃的粗略介紹,請參考此文:三、dynamic programming

二十三、堆排序算法 。     堆排序算法作爲一種快速穩定的算法,其平均時間複雜度(最壞也爲)O(n*lgn)。當然,在實際應用中,一個實現的好的快速排序算法仍然要優於堆排序算法。不過,堆數據結構還可以作爲高效的優先級隊列。對堆排序算法作簡單瞭解,可參考這:堆排序算法

二十四遞歸與回溯算法 。此倆個算法,相信各位比較熟悉,在此不做贅述。  

二十五最長公共子序列     最長公共子序列,英文縮寫爲LCS(Longest Common Subsequence)。其定義是,一個數列 S ,如果分別是兩個或多個已知數列的子序列,且是所有符合此條件序列中最長的,則 S 稱爲已知序列的最長公共子序列。 動態規劃的一個計算最長公共子序列的方法如下:     以兩個序列 X、Y 爲例子: 設有二維數組 f[i][j] 表示 X 的 i 位和 Y 的 j 位之前的最長公共子序列的長度,則有:

      f[1][1] = same(1,1)       f[i][j] = max{f[i-1][j-1]+same(i,j),f[i-1][j],f[i][j-1]}

    其中,same(a,b)當 X 的第 a 位與 Y 的第 b 位完全相同時爲“1”,否則爲“0”。 此時,f[i][j]中最大的數便是 X 和 Y 的最長公共子序列的長度,依據該數組回溯,便可找出最長公共子序列。

    該算法的空間、時間複雜度均爲O(n2),經過優化後,空間複雜度可爲O(n),時間複雜度爲O(nlogn)。更多詳情,參見之前寫的一篇拙文(不過,鑑於寫的糟,日後會重寫):三、dynamic programming

二十六、紅黑樹的算法與實現     關於紅黑樹,linux內核中有實現,本BLOG內也已經寫了4篇紅黑樹系列的文章。詳情,請參考:五(續)、教你透徹瞭解紅 黑樹

二十七、A*搜尋算法 。     相對於BFS、Dijkstra 等算法,A*搜尋算法作爲一種高效的最短路徑搜索算法,如今,已得到日益廣泛的應用。初步瞭解A*搜尋算法的高效及與其它最短路徑算法的比較,請參考此文:一(續)、A*,Dijkstra,BFS算法性能比較及A*算法的應用

二十八、圖像特徵提取與匹配之SIFT算法     sift,尺度不變特徵轉換,是一種電腦視覺的算法用來偵測與描述影像中的局部性特徵,它在空間尺度中尋找極值點,並提取出其位置、尺度、旋轉不變量,此算法由 David Lowe 在1999年所發表,2004年完善總結。關於此算法,請參考如下,粗略介紹:九、圖像特徵提取與匹配之SIFT算 ,利用第三方庫編譯過程:九(續)、sift算法的編譯與實現 ,c語言一步一步實現sift算法:九之再續:一步一步用c語言實現sift算法、上 九之再續:教你一步一步用c語言實現sift算法、下

候選經典算法一直在不斷增補中,估計最後能達到上100種。...

     還猶豫什麼列?快投上您寶貴的一票吧。每人可投多次 票,只要您認爲哪個算法是最爲經典的算法,您就在下面的評論裏寫上它的序號,及算法名稱。     當然,如果上文中不曾出現你認爲最經典的算法,你也可以寫在評論裏,爲你鍾愛的它投上一票。而後我將考慮您的意見,把您鍾愛的算法也作爲一種候選算法,添補上去。:D。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章