當今世界十大經典算法

原文地址:http://blog.csdn.net/wangkechuang/article/details/7896355

    當今世界,已經被發現或創造的經典算法數不勝數。如果,一定要投票選出你最看重的十大算法,你會作何選擇列?有國外網友在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大元素平均複雜度爲O(N)的算法,俗稱"中位數之中位數算法"。這個算法依靠一種精心設計的 pivot 選取方法,即選取中位數的中位數作爲樞紐元,從而保證了在最情況下的也能做到線性時間的複雜度,打敗了平均O(N*logN)、最壞 O(n^2) 複雜度的快速排序算法。

    事實上,這個所謂的BFPRT,就是本blog中闡述過的快速選擇SELECT算法,詳情請參考下列博文:第三章、尋找最小的k個數十四、快速選擇SELECT算法的深入分析與實現。在我的這兩篇文章中,給出了此快速選擇SELECT算法,藉助選取數組中中位數的中位數作爲樞紐元,能做到最壞情況下運行時間爲O(N)的複雜度的證明。

    我在這裏簡單介紹下在數組中選出第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

    並查集是一種樹型的數據結構,用於處理一些不相交集合(Disjoint Sets)的合併及查詢問題。常常在使用中以森林來表示。集就是讓每個元素構成一個單元素的集合,並就是按一定順序將屬於同一組的元素所在的集合合併。並行查找,最終佔據了此份榜單的第一名。

    補充:前三名的投票數,只相差4票,8票。所以這個排名日後還會不斷有所變化。但不管最終結果怎樣,這前十名的算法已經基本敲定了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章