一、排序算法
1、冒泡排序
2、選擇排序
3、插入排序
4、堆排序
5、歸併排序
6、快速排序
{
while (lo < hi) {
while ((lo < hi) && (S[lo] ≤ S[hi]) hi--; while ((lo < hi) && (S[lo] ≤ S[hi]) lo++;
swap(S[lo], S[hi]);
swap(S[lo], S[hi]);
}
return lo;}
二、數據結構之串結構
1、串模式匹配
2、蠻力算法
3、Knuth-Morris-Pratt算法
在最壞情況下蠻力算法的運行時間爲主串、模式串長度的乘積,因此只適用於小規模的串匹配應用。對最壞情況稍加觀察即可發現,之所以需要大量的時間,是因爲存在大量的局部匹配(每一輪的 m 次比較中,只有最後一次是失敗的),實際上,絕大部分的這類字符比較操作都是不必要的,因爲關於主串中此前曾經比較成功過的字符,我們已經掌握了它們的所有信息。只要充分利用這些信息,就可以大大提高匹配算法的效率。
如上圖所示,用T[i]和P[j]分別表示當前正在接受比較的一對字符。當輪比較進行到最後一對字符並發現失配後,蠻力算法將會讓這兩個字符指針回退(即令i = i-j+1和j = 0 ),然後從這一位置繼續比較。事實上,指針i完全不必回退⎯⎯因爲通過前一輪比較我們已經清楚地知道,主串的子串T[i-j..i-1]完全是由字符'0'組成的。因此,在回退之後緊接下來的一輪迭代中,前j-1次比較將註定會成功。既然如此,完全可以讓指針i保持不動並且令j = j-1,然後繼續比較。請注意,如此將可以省去j-1次比較!
上述“i保持不動並且令 j = j-1”的含義,可以理解爲“將 P相對於 T 向右移動一個單元,然後從剛纔失配的位置繼續比較”。實際上,利用以往的成功比較所提供的信息,不僅可以避免主串字符指針的回退,而且有可能使模式串儘可能大跨度地右移。
當本輪比較中發現T[i] ≠ P[7]失配後,應該將模式串P右移多少個單元呢?有必要逐個單元地右移嗎?稍加觀察即可發現,在這一情況下,移動一個、兩個或三個單元都是徒勞的。事實上,根據以往的比較結果,必然有T[i-7..i] = P[0..7] = "CHINCHI" 。如果在此局部能夠實現匹配,則至少在 T[i]左側的那些字符應該是匹配的⎯⎯比如,當 P[0]與 T[i-3]對齊時,就屬於這樣的情況。如果再注意到i-3是能夠如此匹配的最靠左位置,就可以放心地將模式串右移 7-3 = 4個單元,使 i保持不變,令 j= 3,然後繼續比較。
相對於蠻力算法,KMP算法可以避免很多不必要的比較操作,KMP算法的運行時間爲O(n+m),其中 n 和 m 分別文本串和模式串的長度。
4、BM算法
KMP算法的思想可以總結爲:不斷將模式串與文本串比較,一旦局部失配,則利用此前比較給出的信息,儘可能長距離的移動模式串,在比較模式串與文本串時,掃描方向是自左向右,實際上,很多模式匹配算法採用了其他的掃描方向,比如從右向左或者從中間向兩邊,BM算法採用的就是從右向左的掃描次序,該算法的構思是不斷自右向左地比較模式串P與主串T,一旦發現失配,則利用此前掃描所提供的信息,將P右移一定距離,然後重新自右向左掃描比較,該算法有兩種啓發式策略:藉助壞字符和好後綴確定移動的距離,也可將二者結合起來,同時採用。如 圖九.7 所示,在自右向左比較模式串P[0..m-1]與主串的子串T[i..i+m-1]的過程中,假設在P[j]處首次發現失配:T[i+j] = 'b' ≠ 'a' = P[j]。此時,我們應該用P中的哪個字符對準T[i+j]並重新自右向左比較呢?我們注意到,若 P 能夠與 T 的某一(包括 T[i+j]在內的)子串匹配,則必然也應在 T[i+j] = 'b'處匹配;反之,若與 T[i+j]對準的字符不是'b',則不可能匹配。因此,只需將 P 中的每一字符'b'對準T[i+j],然後重新自右向左比較。爲了避免 P 的左移,我們可以選用 P 中最靠右的字符'b'(如果存在的話),將其與 T[i+j]對齊,然後重新做一遍自右向左的掃描比較。具體來說,若 P 中最靠右的字符'b'爲 P[k] = 'b',則 P 的右移量爲 j - k。
特殊情況:
如 圖九.8 所示,P串中不含字符'b',此時可以直接將該串整體移過,用P[0]對準T[i+j+1],然後自右向左繼續比較。 另外,即使 P 串中含有字符'b',卻也有可能出現的位置太靠右,使得 k = BC['b'] ≥ j。在這一情況下,j-k 將不再是正數,若以此距離進行右移,實際效果將是左移⎯⎯顯然,這是不必要的。因此,爲處理這一情況,只需簡單地將 P 串右移一個字符,然後重新自右向左掃描比較。
②好後綴策略
BM算法的思想,是儘可能的利用此前已進行過的比較所提供的信息,以加速模式串的移動,上述壞字符策略,就很好的體現了這一構思,然而,仔細分析後我們發現,壞字符策略只利用了此前失敗的比較所提供的信息,實際上,在失敗之前往往還會有一系列成功的比較,他們也能提供大量的信息,我們利用這些信息加速模式串右移,稱之爲好後綴策略。
三、數據結構之圖
若邊e = (u, v),則頂點u和v也稱作e的端點(End vertices或Endpoints)。如果e是從u指向v的有向邊,則u稱作起點(Origin)或尾端點(Tail),v稱作終點(Destination)或頭端點(Head)。我們也稱u和v是相鄰的(Adjacent),稱e與v、u是相關聯的(Incident)。頂點v的關聯邊的總數,稱爲v的度數(Degree),記作deg(v)。以 圖十.1(a)爲例,有deg(a) = deg(c) = 3。在有向圖中,以u爲起點的有向邊稱作u的出邊(Outgoing edge),以v爲終點的邊則稱作v的入邊(Incoming edge )。v的出邊總數稱作v的出度(Out-degree),記作outdeg(v);入邊總數稱作入度(In-degree),記作indeg(v)。以 圖十.1(c)爲例,有outdeg(a) = indeg(a) = outdeg(c) = indeg(c) =3。
圖中所含的邊並不見得能構成一個集合(Set),準確地說它們構成了一個復集(Multiset)⎯⎯其中允許出現重複的元素。比如,若在某對頂點之間有多條無向邊,或者兩條有向邊的起點和終點完全一樣,就屬於這種情況。這類重複的邊也稱作平行邊(Parallel e dges)或多重邊(Multipleedges)。例如,要是用頂點表示城市,用邊表示城市之間的飛機航線,則有可能在某一對城市之間存在多條航線。無論是無向圖還是有向圖,還有另一種特殊情況:與某條邊關聯的是同一個頂點(如 圖十.1 中的頂點a)⎯⎯這樣的邊稱作自環(Self-loop)。在某些特定的應用問題中,這類邊的確是有意義的⎯⎯比如在城市交通圖中,沿着某條街道,有可能會不經過任何交叉路口而直接返回原處。不過,這些特殊情況通常並不多見。不含上述特殊邊的圖,稱作簡單圖(Simple graph)。對簡單圖而言,其中的邊必然構成一個集合,而且每條邊只能聯接於不同的頂點之間。
④圖的複雜度
設簡單圖G包含n個頂點和m條邊。若 G 是無向圖,則有 m ≤ n(n-1)/2;若 G 是有向圖,則有 m ≤ n(n-1)。
⑤子圖、生成子圖、限制子圖
設G=(V,E)和G‘=(V',E'),如果 V' ⊆ V 且 E' ⊆ E,則稱 G'是 G 的一個子圖,如果 V' = V 且 E' ⊆ E,則稱 G'是 G 的一個生成子圖,若 U ⊆ V,則在刪除 V\U 中的頂點及其關聯邊之後所得到的 G 的子圖,稱爲 G 限制在 U上的子圖,記做 G|U= (U, E|U)。
⑥通路、環路及可達分量
所謂圖中的一條通路或路徑,就是由(不一定互異的)m+1個頂點與m條邊交替構成的一個序列ρ = {v0, e1, v1, e2, v2, ..., em, vm},m ≥ 0,而且 ei= (vi-1, vi),1 ≤ i ≤ m,m稱作該通路的長度,長度m≥1的路徑,若第一個頂點與最後一個頂點相同,則稱之爲環路,如果組成通路ρ的所有頂點各不相同,則稱之爲簡單通路,如果在組成環路的所有頂點中,除v0= v m外均各不相同,則稱之爲簡單環路,如果組成通路ρ的所有邊都是有向邊,而且每一ei都是從vi-1指向vi,1 ≤ i ≤ m,則稱ρ爲有向通路,類似的也可定義有向環路。在圖G=(V,E)中,若記n=|V|,則簡單路徑長度不超過 n-1;長度爲 k 的簡單路徑的總數不超過 n!/(n-k-1)!,1 ≤ k ≤ n-1,G中簡單路徑的數目是有限的。
在有向圖G中,若從頂點s到v有一條通路,則稱v是“從s可達的”,對於指定的頂點s,從s可達的所有頂點所組成的集合,稱作s在G中對應的可達分量,記作Vr(G, s)。
⑦連通性、等價類與連通分量
考察圖 G = ( V, E)。在頂點 u, v ∈ V 之間,如果既存在一條從 u 到 v 的通路ρ(u, v),也存在一條從v到u的通路ρ(v, u),則稱u和v是連通的,記作u ~ v。實際上,若 G 是無向圖,則“ρ(u, v)存在”當且僅當“ρ(v, u)存在”。而對於有向圖 G 來說,“ρ(u,v)和ρ(v, u)同時存在”即意味着“存在一條同時經過 u 和 v 的環路”。故此,有向圖中相互連通的頂點也被稱爲是互相“強連通的”。在有向圖中,由一組相互強連通的頂點構成的極大集合,稱作一個強連通分量。若u~v,則必然存在一條經過u和v的環路,而且對於該環路上的任一頂點w,都有w~u和w~v。連通關係“~”滿足如下性質:反身性:對於任何頂點 v,都有 v ~ v 成立;對稱性:u~v僅當v~u;傳遞性:對於任何頂點u、v和w,只要u~v且v~w,則必有u~w。
⑧森林、樹及無向圖的生成樹
考察無向圖G=(V,E),若G中不含任何環路,則稱之爲森林,連通的森林(任何兩個頂點都是連通的)稱作樹。若G爲由n個頂點與m條邊組成一幅無向圖,若G是連通的,則m≥n-1,若G是一棵樹,則m=n-1,若G是森林,則m≤n-1。若G的某一生成子圖G‘爲一棵樹,則稱G’爲G的一顆生成樹。
⑨有向圖的生成樹
在有向圖G=(V,E)中,若存在某個頂點s滿足Vr(G, s) = V(即從s可到達所有頂點)且s到任一頂點的通路唯一,同時G中不含迴路,則稱G爲一顆以s爲根的有向樹。
⑩帶權網絡
有些時候,圖不僅需要表示元素之間是否存在某種關係,而且還需要表示這一關係的某一細節,以鐵路運輸爲例,可以用頂點表示城市,用頂點之間的邊表示城市之間是否有鐵路聯接,然而,爲了更爲細緻地描述鐵路運輸網,還需要記錄每段鐵路的長度、運輸成本等信息,爲適應這類應用的需求,我們需要爲每條邊設置相應的數據域,以記錄對應的信息,對於任一邊 e ∈ E,weight(e)稱作 e 的權重 ,引入權重函數之後的圖G(V,E,weight()),稱作帶權圖或帶權網絡,有時也簡稱爲網絡。