1. 程式人生 > >讓你輕鬆進階高手的十大演算法

讓你輕鬆進階高手的十大演算法

演算法一:快速排序演算法

快速排序是由東尼·霍爾所發展的一種排序演算法。在平均狀況下,排序 n 個專案要Ο(n log n)次比較。在最壞狀況下則需要Ο(n2)次比較,但這種狀況並不常見。事實上,快速排序通常明顯比其他Ο(n log n) 演算法更快,因為它的內部迴圈(inner loop)可以在大部分的架構上很有效率地被實現出來。 
快速排序使用分治法(Divide and conquer)策略來把一個序列(list)分為兩個子序列(sub-lists)。 

演算法步驟: 
1 從數列中挑出一個元素,稱為 “基準”(pivot), 
2 重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的後面(相同的數可以到任一邊)。在這個分割槽退出之後,該基準就處於數列的中間位置。這個稱為分割槽(partition)操作。 

3 遞迴地(recursive)把小於基準值元素的子數列和大於基準值元素的子數列排序。 
遞迴的最底部情形,是數列的大小是零或一,也就是永遠都已經被排序好了。雖然一直遞迴下去,但是這個演算法總會退出,因為在每次的迭代(iteration)中,它至少會把一個元素擺到它最後的位置去。 

 

演算法二:堆排序演算法

堆排序(Heapsort)是指利用堆這種資料結構所設計的一種排序演算法。堆積是一個近似完全二叉樹的結構,並同時滿足堆積的性質:即子結點的鍵值或索引總是小於(或者大於)它的父節點。 

堆排序的平均時間複雜度為Ο(nlogn) 。 
演算法步驟: 
建立一個堆H[0..n-1] 
把堆首(最大值)和堆尾互換 

3. 把堆的尺寸縮小1,並呼叫shift_down(0),目的是把新的陣列頂端資料調整到相應位置 
4. 重複步驟2,直到堆的尺寸為1 

 

演算法三:歸併排序

歸併排序(Merge sort,臺灣譯作:合併排序)是建立在歸併操作上的一種有效的排序演算法。該演算法是採用分治法(Divide and Conquer)的一個非常典型的應用。 

演算法步驟: 
1. 申請空間,使其大小為兩個已經排序序列之和,該空間用來存放合併後的序列 
2. 設定兩個指標,最初位置分別為兩個已經排序序列的起始位置 
3. 比較兩個指標所指向的元素,選擇相對小的元素放入到合併空間,並移動指標到下一位置 
4. 重複步驟3直到某一指標達到序列尾 

5. 將另一序列剩下的所有元素直接複製到合併序列尾 

 

演算法四:二分查詢演算法

二分查詢演算法是一種在有序陣列中查詢某一特定元素的搜尋演算法。搜素過程從陣列的中間元素開始,如果中間元素正好是要查詢的元素,則搜 素過程結束;如果某一特定元素大於或者小於中間元素,則在陣列大於或小於中間元素的那一半中查詢,而且跟開始一樣從中間元素開始比較。如果在某一步驟陣列 為空,則代表找不到。這種搜尋演算法每一次比較都使搜尋範圍縮小一半。折半搜尋每次把搜尋區域減少一半,時間複雜度為Ο(logn) 。 

演算法五:BFPRT(線性查詢演算法)

BFPRT演算法解決的問題十分經典,即從某n個元素的序列中選出第k大(第k小)的元素,通過巧妙的分 析,BFPRT可以保證在最壞情況下仍為線性時間複雜度。該演算法的思想與快速排序思想相似,當然,為使得演算法在最壞情況下,依然能達到o(n)的時間複雜 度,五位演算法作者做了精妙的處理。 

演算法步驟: 
1. 將n個元素每5個一組,分成n/5(上界)組。 
2. 取出每一組的中位數,任意排序方法,比如插入排序。 
3. 遞迴的呼叫selection演算法查詢上一步中所有中位數的中位數,設為x,偶數箇中位數的情況下設定為選取中間小的一個。 
4. 用x來分割陣列,設小於等於x的個數為k,大於x的個數即為n-k。 
5. 若i==k,返回x;若i<k,在小於x的元素中遞迴查詢第i小的元素;若i>k,在大於x的元素中遞迴查詢第i-k小的元素。 
終止條件:n=1時,返回的即是i小元素。 

演算法六:DFS(深度優先搜尋)

深度優先搜尋演算法(Depth-First-Search),是搜尋演算法的一種。它沿著樹的深度遍歷樹的節點,儘可能深的搜尋樹的分 支。當節點v 的所有邊都己被探尋過,搜尋將回溯到發現節點v的那條邊的起始節點。這一過程一直進行到已發現從源節點可達的所有節點為止。如果還存在未被髮 現的節點,則選擇其中一個作為源節點並重復以上過程,整個程序反覆進行直到所有節點都被訪問為止。DFS屬於盲目搜尋。 

深度優先搜尋是圖論中的經典演算法,利用深度優先搜尋演算法可以產生目標圖的相應拓撲排序表,利用拓撲排序表可以方便的解決很多相關的圖論問題,如最大路徑問題等等。一般用堆資料結構來輔助實現DFS演算法。 

深度優先遍歷圖演算法步驟: 
1. 訪問頂點v; 
2. 依次從v的未被訪問的鄰接點出發,對圖進行深度優先遍歷;直至圖中和v有路徑相通的頂點都被訪問; 
3. 若此時圖中尚有頂點未被訪問,則從一個未被訪問的頂點出發,重新進行深度優先遍歷,直到圖中所有頂點均被訪問過為止。 
上述描述可能比較抽象,舉個例項: 
DFS 在訪問圖中某一起始頂點 v 後,由 v 出發,訪問它的任一鄰接頂點 w1;再從 w1 出發,訪問與 w1鄰 接但還沒有訪問過的頂點 w2;然後再從 w2 出發,進行類似的訪問,… 如此進行下去,直至到達所有的鄰接頂點都被訪問過的頂點 u 為止。 
接著,退回一步,退到前一次剛訪問過的頂點,看是否還有其它沒有被訪問的鄰接頂點。如果有,則訪問此頂點,之後再從此頂點出發,進行與前述類似的訪問;如果沒有,就再退回一步進行搜尋。重複上述過程,直到連通圖中所有頂點都被訪問過為止。 

演算法七:BFS(廣度優先搜尋)

廣度優先搜尋演算法(Breadth-First-Search),是一種圖形搜尋演算法。簡單的說,BFS是從根節點開始,沿著樹(圖)的寬度遍歷樹(圖)的節點。如果所有節點均被訪問,則演算法中止。BFS同樣屬於盲目搜尋。一般用佇列資料結構來輔助實現BFS演算法。 

演算法步驟: 
1. 首先將根節點放入佇列中。 
2. 從佇列中取出第一個節點,並檢驗它是否為目標。 
如果找到目標,則結束搜尋並回傳結果。 
否則將它所有尚未檢驗過的直接子節點加入佇列中。 
3. 若佇列為空,表示整張圖都檢查過了——亦即圖中沒有欲搜尋的目標。結束搜尋並回傳“找不到目標”。 
4. 重複步驟2。 

 

演算法八:Dijkstra演算法

戴克斯特拉演算法(Dijkstra’s algorithm)是由荷蘭電腦科學家艾茲赫爾·戴克斯特拉提出。迪科斯徹演算法使用了廣度優先搜尋解決非負權有向圖的單源最短路徑問題,演算法最終得到一個最短路徑樹。該演算法常用於路由演算法或者作為其他圖演算法的一個子模組。 

該演算法的輸入包含了一個有權重的有向圖 G,以及G中的一個來源頂點 S。我們以 V 表示 G 中所有頂點的集合。每一個圖中的邊,都是兩個頂點所形成的有序元素對。(u, v) 表示從頂點 u 到 v 有路徑相連。我們以 E 表示G中所有邊的集合,而邊的權重則由權重函式 w: E → [0, ∞] 定義。因此,w(u, v) 就是從頂點 u 到頂點 v 的非負權重(weight)。邊的權重可以想像成兩個頂點之間的距離。任兩點間路徑的權重,就是該路徑上所有邊的權重總和。已知有 V 中有頂點 s 及 t,Dijkstra 演算法可以找到 s 到 t的最低權重路徑(例如,最短路徑)。這個演算法也可以在一個圖中,找到從一個頂點 s 到任何其他頂點的最短路徑。對於不含負權的有向圖,Dijkstra演算法是目前已知的最快的單源最短路徑演算法。 

演算法步驟: 
1. 初始時令 S={V0},T={其餘頂點},T中頂點對應的距離值 
若存在<v0,vi>,d(V0,Vi)為<v0,vi>弧上的權值 
若不存在<v0,vi>,d(V0,Vi)為∞ 
2. 從T中選取一個其距離值為最小的頂點W且不在S中,加入S 
3. 對其餘T中頂點的距離值進行修改:若加進W作中間頂點,從V0到Vi的距離值縮短,則修改此距離值 
重複上述步驟2、3,直到S中包含所有頂點,即W=Vi為止 

 

演算法九:動態規劃演算法

動態規劃(Dynamic programming)是一種在數學、電腦科學和經濟學中使用的,通過把原問題分解為相對簡單的子問題的方式求解複雜問題的方法。 動態規劃常常適用於有重疊子問題和最優子結構性質的問題,動態規劃方法所耗時間往往遠少於樸素解法。 

動態規劃背後的基本思想非常簡單。大致上,若要解一個給定問題,我們需要解其不同部分(即子問題),再合併子問題的解以得出原問題的解。 通常許多 子問題非常相似,為此動態規劃法試圖僅僅解決每個子問題一次,從而減少計算量: 一旦某個給定子問題的解已經算出,則將其記憶化儲存,以便下次需要同一個 子問題解之時直接查表。 這種做法在重複子問題的數目關於輸入的規模呈指數增長時特別有用。 

關於動態規劃最經典的問題當屬揹包問題。 

演算法步驟: 
1. 最優子結構性質。如果問題的最優解所包含的子問題的解也是最優的,我們就稱該問題具有最優子結構性質(即滿足最優化原理)。最優子結構性質為動態規劃演算法解決問題提供了重要線索。 
2. 子問題重疊性質。子問題重疊性質是指在用遞迴演算法自頂向下對問題進行求解時,每次產生的子問題並不總是新問題,有些子問題會被重複計算多次。 動態規劃演算法正是利用了這種子問題的重疊性質,對每一個子問題只計算一次,然後將其計算結果儲存在一個表格中,當再次需要計算已經計算過的子問題時,只是 在表格中簡單地檢視一下結果,從而獲得較高的效率。 

演算法十:樸素貝葉斯分類演算法

樸素貝葉斯分類演算法是一種基於貝葉斯定理的簡單概率分類演算法。貝葉斯分類的基礎是概率推理,就是在各種條件的存在不確定,僅知其出現概率的情況下, 如何完成推理和決策任務。概率推理是與確定性推理相對應的。而樸素貝葉斯分類器是基於獨立假設的,即假設樣本每個特徵與其他特徵都不相關。 
樸素貝葉斯分類器依靠精確的自然概率模型,在有監督學習的樣本集中能獲取得非常好的分類效果。在許多實際應用中,樸素貝葉斯模型引數估計使用最大似然估計方法,換言之樸素貝葉斯模型能工作並沒有用到貝葉斯概率或者任何貝葉斯模型。 

相關推薦

輕鬆高手演算法

演算法一:快速排序演算法快速排序是由東尼·霍爾所發展的一種排序演算法。在平均狀況下,排序 n 個專案要Ο(n log n)次比較。在最壞狀況下則需要Ο(n2)次比較,但這種狀況並不常見。事實上,快速排序通常明顯比其他Ο(n log n) 演算法更快,因為它的內部迴圈(inn

機器學習 (二)輕鬆理解K-means 聚類演算法

前言        你還記得菜市場賣菜的嗎?書店賣書的或者是平時去超市買東西時的物品,它們是不是都根據相似性擺放在一起了呢,飲料、啤酒、零食分佈在各自區域,像這樣各級事物的相似特點或特性組織在一起的方法,在機器學習裡面即成為

Photoshop零基礎教程集錦,助快速佬,輕鬆、任性!!!

現今,對於Web或App UI設計師而言,除了不斷學習專業知識,提升設計技能。掌握一款得心應手的設計工具(例如設計師們常用的影象處理工具PhotoShop,向量圖繪製工具AI, 圖形視訊處理工具AE, 設計稿原型化的原型設計工具Mockplus, 以及線上協作設計工具摹客iDoc等等),快速高效的呈

JVM菜鳥高手之路(基礎知識開場白)

由於 重要性 基礎 陌生 bsp 參數 高手之路 開發人員 基礎知識 轉載請註明原創出處,謝謝! 最近沒有什麽實戰,準備把JVM知識梳理一遍,先以開發人員的交流來談談jvm這塊的知識以及重要性,依稀記得2、3年前用solr的時候老是經常oom,提到oom大家應該都不陌生,那

Android高手教程(六)之---Android中萬能的BaseAdapter(Spinner,ListView,GridView)的使用!

private idt save idv -- imp drawable android中 welcome 大家好!今天給大家講解一下BaseAdapter(基礎適配器)的用法,適配器的作用主要是用來給諸如(Spinner,ListView,GridView)來填充數據的。

6社群運營技巧,輕鬆度過新媒體寒冬

最近一段時間,自媒體行業很不太平。 繼“傅首爾”、“紫竹張先生”、“有束光”等9800個自媒體賬號被封停後不久,企圖“重生”的相關小號也在幾天前被微信團隊再次封停。 行業開始熱議此次“史上最強自媒體整頓”,有人抱不平,更多人對此大感快慰。 新媒體逐漸規範當然是好事,而熱議背後,能明顯感受到從

Java四 Integer與int的種種比較知道多少

包裝 之間 www. tex -128 function detail content aqi Java進階(三十四)Integer與int的種種比較你知道多少? 前言 如果面試官問Integer與int的區別:估計大多數人只會說到兩點:Inge

AngularJS(三一)AngularJS項目開發技巧之獲取模態對話框中的組件ID

ng- 美圖 控件 div one 思考 span ava layui AngularJS項目開發技巧之獲取模態對話框中的組件ID 需求 出於項目開發需求,須要實現的業務邏輯是:藥店端點擊查看“已發貨”“已收貨”訂單詳情時。模塊彈出框中僅僅應出現“取消”bu

課 Python模塊之calendar

pri 第一個 紀元 間隔 calendar類 模塊 OS 文件 tps calendar,是與日歷相關的模塊。calendar模塊文件裏定義了很多類型,主要有Calendar,TextCalendar以及HTMLCalendar類型。其中,Calendar是TextCal

二課 Python模塊之sys

read OS python模塊 leg gac pack uil file pos sys是與Python解釋器交互的工具。 先看下dir(sys) >>> import sys >>> dir(sys) [‘__displayhoo

五課 Python模塊之Numpy

忽略 作用 擴展 .sh error pty logic 給定 線性 轉 從一位大神哪裏轉過來的,大家一起學習吧。今後會逐步增加示例代碼。 NumPy   NumPy是高性能科學計算和數據分析的基礎包。部分功能如下: ndarray, 具有矢量算術運算和復雜廣播能力

六課 Python模塊之Pandas

des unique port date 創建索引 uniq 默認 使用 模塊 轉 同十五課,都是從大神那裏轉載的。今後會逐步增加示例代碼。 Pandas pandas 是基於NumPy 的一種工具,該工具是為了解決數據分析任務而創建的。Pandas 納入了大

八顆 Python對文件的操作

appdata ren 文檔 只讀 路徑和 users python admin 分別是 在Windows中,我們可以很容易地創建、修改和刪除文件。我們熟悉的文件類型也有很多:txt、mkv、mp3、docx... 在Python中,我們依舊可以執行創建、修改和刪除文件的操

德到課堂---必須要懂的職場生存法則

活著 空間 可能 你會 是個 坐標 能說 孤單 得到 德到領袖與你分享:你必須要懂的十大職場生存法則在職場中,總需要有一些生存規則,那麽什麽樣的生存法則才適用呢,今天就來分享一下你必須要懂的十大職場中的生存規律。 01十大職場生存規律 第一:男女搭檔幹活不累。  在辦公室裏

CSS一)position:fixed

容器 hid ali overflow lin 元素 -a idt fixed 固定定位元素的包含快是根元素 類似於無依賴的絕對定位,利用無依賴的固定定位也可以在元素內部實現一個fixed定位 <div class="father"> <div cla

CSS)position:relative

ati 進階 最小化 相對 pan style 而不是 原則 round 定位位移相對於自身進行偏移定位 相對定位元素的 left/top/right/bottom 的百分比值是相對於包含塊計算的,而不是自身 與絕對定位元素的對立方向不同,top/bottom 同時使 用的

CSS四)font-family

中文 class 技術分享 png clas info pre 寬度 空格 font-family font-family: serif; /* 襯線字體 */ font-family: sans-serif; /* 無襯線字體 */ font-family支持字體族

CSS九)文本控制

bre spa div 切換效果 nowrap align 分隔 下劃線 效果 text-indent 應用 (1)使用 text-indent 負值隱藏文本內容,例如網站標頭 (2)使用text-indent的百分比值來實現寬度已知的內聯子元素居中 letter-spac

java程式設計師菜鳥七)linux基礎入門(五)linux檔案/目錄的許可權和歸屬管理

在linux中的每一個檔案或目錄都包含有訪問許可權,這些訪問許可權決定了誰能訪問和如何訪問這些檔案和目錄。相應的每一個檔案和目錄都有所屬的屬主和屬組,合理的設定檔案和目錄的屬組和屬主在檔案/目錄管理中佔據著很重要的地位,所以,今天我就和大家一起來看一下有關檔案/目錄的許可權和歸屬的相關設定

java程式設計師菜鳥六)linux基礎入門(四)linux下VIM文字編輯器使用

  linux下編寫配置檔案最好的編輯工具莫過於vim了。Vim的功能實在太多太全,Vim的很多功能也許我們很少用得到,真正為大家常用的功能可能只佔到所有功能的冰山一角。Vim終歸只是一個編寫程式碼或編輯文件的工具,所以只要掌握一些足夠我們使用的功能即可。 做個廣告