本文僅僅是爲了快速理解掌握多個經典算法類型而總結的思想性概要,並無算法實現。
1. 遞歸
遞歸算法的經典實例爲漢諾塔問題和全排列問題,在此對漢諾塔問題簡單總結一下。
假設f(n-1)已經解決,如何解決f(n)問題,也就是說假設n-1個圓盤的順序已經安放正確,如何正確安放第n個圓盤, 使得所有n個圓盤安放正確。
Hanoi(n,A,B,C)
if n=1
將圓盤從A移動到C
else
Hanoi(n-1,A,C,B)//藉助C,將n-1個圓盤從A移動到B
將第n個圓盤移動到C
Hanoi(n-1,B,A,C)//藉助A,將剩下n-1個圓盤從B移動到C
具體過程可以根據僞碼畫出遞歸樹,並寫出遞歸方程,進行算法分析。
2. 分治
分置即分而治之。主要分爲三個步驟:劃分、治(解決)、合併。經典應用有合併排序,快速排序和矩陣乘法等。
A 、 合併排序:將整個數組中的所有元素進行多次劃分,比如使用二分,直到劃分成一個個獨立的元素,此爲 分;然後每兩個元素進行比較並重新排序,此爲治;將重新排序的元素再逐次合併成整個數組,此爲合。
MergeSort(A,p,r)
if p<r
q=(p+r)/2 //找劃分點
MergeSort(A,p,q) //劃分
MergeSort(A,q+1,r) //劃分
Merge(A,p,q,r) //治(排序)+合併
B、快速排序:取第一個元素爲標記元素,從後往前,依次與每個元素比較,直到一個比自己小的元素a,此時 將該元素放到標記元素的位置上,即覆蓋第一個元素,再從前到後依次與每個元素比較,直到找到一個比自 己大的元素b,此時將該元素覆蓋a,再從後往前進行類似的過程,覆蓋b,最後的一個元素用標記元素覆蓋 上,這裏要注意的是每次劃分的標記元素都是不改變的,此時標記元素就有一個最終的位置p,p前面的元素 都比標記元素小,後面的都比它大。然後再對p的左邊和右邊分別進行快速排序即可。
QuickSort(A,p,r)
if p<r
q=Partition(A,p,r)
QuickSort(A,p,q-1)
QuickSort(A,q+1,r)
3. 動態規劃
動態規劃利用了分治的思想,將問題分成很多個子問題,自底向上迭代求解每個子問題的解並記錄子問題的解,最後合併成整個問題的解。這樣在求解子問題的時候直接查表,就不會重複求解了。典型的問題有裝配線調度,矩陣連乘,0/1揹包,最長公共子序列,最優二叉搜索樹等問題。實質上就是填表的過程。
A、裝配線調度:從初始點開始向終止點計算,裝配線1上的某一點的代價有兩種可能值,第一種爲由本條裝配線的前一點直接過渡到這個點的值m=本條裝配線上一步代價+本次代價,第二種爲由裝配線2轉移得到的值n=裝配線2上一步代價+轉移代價+本次代價;同理裝配線2的某一點的代價也有兩種可能值,求法與前面類似;每次擴展一個點就比較一下m和n的值,選擇小的即爲當前點的調度方案,當從頭到尾每個點都擴展之後就能得到裝配線調度問題的完整解。
B、矩陣連乘:解決這個問題需要一個三重循環,計算矩陣序列的每個可能的分段點的左邊序列的連乘代價和右邊序列的連乘代價,再加上二者和分段點連乘的代價即爲這種分段方法的總代價,每次循環都選擇當前分段方法的最小代價,最後就能得出最小代價的分段方法。
C、0/1揹包:在裝物品時有兩種選擇,第一種是容量不足,無法裝,則最優選擇爲當前狀態;第二種是容量充足,選擇裝與不裝,若裝,則求得一價值m,若不裝,則爲當前價值n,比較m,n並填表。
4. 貪心算法
貪心算法在大多數情況下能得到最優解,即使找不到,其近似解也讓人滿意。思想就是每一步都選擇最優決策。主要應用爲任務選擇,揹包問題等。
A、任務選擇問題:任務選擇問題就是從一系列的任務中選擇一個任務序列滿足時序的情況下而任務數最多。首先對任務依照完成時間進行排序,每次選擇完成時間最小的任務加入序列,直到不滿足總時間的限制,即得到任務數最多的任務序列。
B、揹包問題:即可分割的揹包問題。對每個物品的單位重量從大到小排序,每次選擇單位重量最大的物品直到揹包裝滿爲止(物品可分割)。