有關匹配和排序的演算法,高手幫幫忙哈

時間 2021-07-12 17:32:25

1樓:

一、插入排序(insertion sort)

1. 基本思想:

每次將一個待排序的資料元素,插入到前面已經排好序的數列中的適當位置,使數列依然有序;直到待排序資料元素全部插入完為止。

2. 排序過程:

【示例】:

[初始關鍵字] [49] 38 65 97 76 13 27 49

j=2(38) [38 49] 65 97 76 13 27 49

j=3(65) [38 49 65] 97 76 13 27 49

j=4(97) [38 49 65 97] 76 13 27 49

j=5(76) [38 49 65 76 97] 13 27 49

j=6(13) [13 38 49 65 76 97] 27 49

j=7(27) [13 27 38 49 65 76 97] 49

j=8(49) [13 27 38 49 49 65 76 97]

procedure insertsort(var r : filetype);

//對r[1..n]按遞增序進行插入排序, r[0]是監視哨//

begin

for i := 2 to n do //依次插入r[2],...,r[n]//

begin

r[0] := r[i]; j := i - 1;

while r[0] < r[j] do //查詢r[i]的插入位置//

begin

r[j+1] := r[j]; //將大於r[i]的元素後移//

j := j - 1

endr[j + 1] := r[0] ; //插入r[i] //

endend; //insertsort //

二、選擇排序

1. 基本思想:

每一趟從待排序的資料元素中選出最小(或最大)的一個元素,順序放在已排好序的數列的最後,直到全部待排序的資料元素排完。

2. 排序過程:

【示例】:

初始關鍵字 [49 38 65 97 76 13 27 49]

第一趟排序後 13 〔38 65 97 76 49 27 49]

第二趟排序後 13 27 〔65 97 76 49 38 49]

第三趟排序後 13 27 38 [97 76 49 65 49]

第四趟排序後 13 27 38 49 [49 97 65 76]

第五趟排序後 13 27 38 49 49 [97 97 76]

第六趟排序後 13 27 38 49 49 76 [76 97]

第七趟排序後 13 27 38 49 49 76 76 [ 97]

最後排序結果 13 27 38 49 49 76 76 97

procedure selectsort(var r : filetype); //對r[1..n]進行直接選擇排序 //

begin

for i := 1 to n - 1 do //做n - 1趟選擇排序//

begin

k := i;

for j := i + 1 to n do //在當前無序區r[i..n]中選最小的元素r[k]//

begin

if r[j] < r[k] then k := j

end;

if k <>; i then //交換r[i]和r[k] //

begin temp := r[i]; r[i] := r[k]; r[k] := temp; end;

endend; //selectsort //

三、氣泡排序(bubblesort)

1. 基本思想:

兩兩比較待排序資料元素的大小,發現兩個資料元素的次序相反時即進行交換,直到沒有反序的資料元素為止。

2. 排序過程:

設想被排序的陣列r〔1..n〕垂直豎立,將每個資料元素看作有重量的氣泡,根據輕氣泡不能在重氣泡之下的原則,從下往上掃描陣列r,凡掃描到違反本原則的輕氣泡,就使其向上"漂浮",如此反覆進行,直至最後任何兩個氣泡都是輕者在上,重者在下為止。

【示例】:

49 13 13 13 13 13 13 13

38 49 27 27 27 27 27 27

65 38 49 38 38 38 38 38

97 65 38 49 49 49 49 49

76 97 65 49 49 49 49 49

13 76 97 65 65 65 65 65

27 27 76 97 76 76 76 76

49 49 49 76 97 97 97 97

procedure bubblesort(var r : filetype) //從下往上掃描的起泡排序//

begin

for i := 1 to n-1 do //做n-1趟排序//

begin

noswap := true; //置未排序的標誌//

for j := n - 1 downto 1 do //從底部往上掃描//

begin

if r[j+1]< r[j] then //交換元素//

begin

temp := r[j+1]; r[j+1 := r[j]; r[j] := temp;

noswap := false

end;

end;

if noswap then return//本趟排序中未發生交換,則終止演算法//

endend; //bubblesort//

四、快速排序(quick sort)

1. 基本思想:

在當前無序區r[1..h]中任取一個資料元素作為比較的"基準"(不妨記為x),用此基準將當前無序區劃分為左右兩個較小的無序區:r[1..

i-1]和r[i+1..h],且左邊的無序子區中資料元素均小於等於基準元素,右邊的無序子區中資料元素均大於等於基準元素,而基準x則位於最終排序的位置上,即r[1..i-1]≤x.

key≤r[i+1..h](1≤i≤h),當r[1..i-1]和r[i+1..

h]均非空時,分別對它們進行上述的劃分過程,直至所有無序子區中的資料元素均已排序為止。

2. 排序過程:

【示例】:

初始關鍵字 [49 38 65 97 76 13 27 49〕

第一次交換後 〔27 38 65 97 76 13 49 49〕

第二次交換後 〔27 38 49 97 76 13 65 49〕

j向左掃描,位置不變,第三次交換後 〔27 38 13 97 76 49 65 49〕

i向右掃描,位置不變,第四次交換後 〔27 38 13 49 76 97 65 49〕

j向左掃描 〔27 38 13 49 76 97 65 49〕

(一次劃分過程)

初始關鍵字 〔49 38 65 97 76 13 27 49〕

一趟排序之後 〔27 38 13〕 49 〔76 97 65 49〕

二趟排序之後 〔13〕 27 〔38〕 49 〔49 65〕76 〔97〕

三趟排序之後 13 27 38 49 49 〔65〕76 97

最後的排序結果 13 27 38 49 49 65 76 97

各趟排序之後的狀態

procedure parttion(var r : filetype; l, h : integer; var i : integer);

//對無序區r[1,h]做劃分,i給以出本次劃分後已被定位的基準元素的位置 //

begin

i := 1; j := h; x := r[i] ;//初始化,x為基準//

repeat

while (r[j] >;= x) and (i < j) do

begin

j := j - 1 //從右向左掃描,查詢第1個小於 x的元素//

if i < j then //已找到r[j] 〈x//

begin

r[i] := r[j]; //相當於交換r[i]和r[j]//

i := i + 1

end;

while (r[i] <= x) and (i < j) do

i := i + 1 //從左向右掃描,查詢第1個大於 x的元素///

end;

if i < j then //已找到r[i] >; x //

begin r[j] := r[i]; //相當於交換r[i]和r[j]//

j := j - 1

enduntil i = j;

r[i] := x //基準x已被最終定位//

end; //parttion //

procedure quicksort(var r :filetype; s,t: integer); //對r[s..t]快速排序//

begin

if s < t then //當r[s..t]為空或只有一個元素是無需排序//

begin

partion(r, s, t, i); //對r[s..t]做劃分//

quicksort(r, s, i-1);//遞迴處理左區間r[s,i-1]//

quicksort(r, i+1,t);//遞迴處理右區間r[i+1..t] //

end;

end; //quicksort//

五、堆排序(heap sort)

1. 基本思想:

堆排序是一樹形選擇排序,在排序過程中,將r[1..n]看成是一顆完全二叉樹的順序儲存結構,利用完全二叉樹中雙親結點和孩子結點之間的內在關係來選擇最小的元素。

2. 堆的定義: n個元素的序列k1,k2,k3,...,kn.稱為堆,當且僅當該序列滿足特性:

ki≤k2i ki ≤k2i+1(1≤ i≤ [n/2])

堆實質上是滿足如下性質的完全二叉樹:樹中任一非葉子結點的關鍵字均大於等於其孩子結點的關鍵字。例如序列10,15,56,25,30,70就是一個堆,它對應的完全二叉樹如上圖所示。

這種堆中根結點(稱為堆頂)的關鍵字最小,我們把它稱為小根堆。反之,若完全二叉樹中任一非葉子結點的關鍵字均大於等於其孩子的關鍵字,則稱之為大根堆。

3. 排序過程:

堆排序正是利用小根堆(或大根堆)來選取當前無序區中關鍵字小(或最大)的記錄實現排序的。我們不妨利用大根堆來排序。每一趟排序的基本操作是:

將當前無序區調整為一個大根堆,選取關鍵字最大的堆頂記錄,將它和無序區中的最後一個記錄交換。這樣,正好和直接選擇排序相反,有序區是在原記錄區的尾部形成並逐步向前擴大到整個記錄區。

【示例】:對關鍵字序列42,13,91,23,24,16,05,88建堆

procedure sift(var r :filetype; i, m : integer);

//在陣列r[i..m]中呼叫r[i],使得以它為完全二叉樹構成堆。事先已知其左、右子樹(2i+1 <=m時)均是堆//

begin

x := r[i]; j := 2*i; //若j <=m, r[j]是r[i]的左孩子//

while j <= m do //若當前被調整結點r[i]有左孩子r[j]//

begin

if (j < m) and r[j].key < r[j+1].key then

j := j + 1 //令j指向關鍵字較大的右孩子//

//j指向r[i]的左、右孩子中關鍵字較大者//

if x.key < r[j].key then //孩子結點關鍵字較大//

begin

r[i] := r[j]; //將r[j]換到雙親位置上//

i := j ; j := 2*i //繼續以r[j]為當前被調整結點往下層調整//

end;

else

exit//調整完畢,退出迴圈//

endr[i] := x;//將最初被調整的結點放入正確位置//

end;//sift//

procedure heapsort(var r : filetype); //對r[1..n]進行堆排序//

begin

for i := n div downto 1 do //建立初始堆//

sift(r, i , n)

for i := n downto 2 do //進行n-1趟排序//

begin

t := r[1]; r[1] := r[i]; r[i] := t;//將當前堆頂記錄和堆中最後一個記錄交換//

sift(r, 1, i-1) //將r[1..i-1]重成堆//

endend; //heapsort//

六、幾種排序演算法的比較和選擇

1. 選取排序方法需要考慮的因素:

(1) 待排序的元素數目n;

(2) 元素本身資訊量的大小;

(3) 關鍵字的結構及其分佈情況;

(4) 語言工具的條件,輔助空間的大小等。

2. 小結:

(1) 若n較小(n <= 50),則可以採用直接插入排序或直接選擇排序。由於直接插入排序所需的記錄移動操作較直接選擇排序多,因而當記錄本身資訊量較大時,用直接選擇排序較好。

(2) 若檔案的初始狀態已按關鍵字基本有序,則選用直接插入或氣泡排序為宜。

(3) 若n較大,則應採用時間複雜度為o(nlog2n)的排序方法:快速排序、堆排序或歸併排序。 快速排序是目前基於比較的內部排序法中被認為是最好的方法。

(4) 在基於比較排序方法中,每次比較兩個關鍵字的大小之後,僅僅出現兩種可能的轉移,因此可以用一棵二叉樹來描述比較判定過程,由此可以證明:當檔案的n個關鍵字隨機分佈時,任何藉助於"比較"的排序演算法,至少需要o(nlog2n)的時間。

(5) 當記錄本身資訊量較大時,為避免耗費大量時間移動記錄,可以用連結串列作為儲存結構。

有關網路限速的問題,請高手幫幫忙

跟我以前一樣!在鄭州上學時,就在學校對面的村裡租了個房子。然後從房東那裡連根線,鐵通的,網速一般。由於是多人共用一條線,一有人下東西,那就完了 基本就能上qq!可咱好歹也是飢渴系的,不會程式設計,用現成的還是沒問題,於是找到了網路 很小的軟體,功能很少但夠用 能把區域網內所有 使用者顯示出來,能監控...

有關acm演算法的一道題,請各位大牛幫幫忙

while scanf d a eof 程式需要可以輸入多組資料的啊,不是演算法的問題,而是 不符合要求 我的回答多餘了 呵呵 這個應該是杭電的一道acm題目 超時是你沒有注意到多組資料的輸入,基於樓上的給你介紹了 我給你介紹下基本的acm輸入模式 一般題目沒有說明就是預設讀到eof就結束 既採用這...

鍛鍊腹肌的高手幫幫忙

躺在下斜45度或角度更大的斜板上,腹肌收縮用力,使上體儘量上抬,到達最高點腹肌收縮用力並控制,稍停,再以腹肌的張力控制並還原。5次為一組,共做3組,每組之間休息60秒。主要鍛鍊你那兩塊不明顯的上腹肌。你可以負重仰臥起坐,就是在手上拿個重物抱著後腦勺,要從輕的物體開始做一組,在加重量做一組,快不行了就...