編寫直接插入排序演算法,使得查詢插入位置時不是採用順序的方

2021-04-18 21:09:27 字數 7267 閱讀 4006

1樓:匿名使用者

#include

#define length 20

void sequencesearch(int *fp,int length);

void search(int *fp,int length);

void sort(int *fp,int length);

void main()

while (choise==1||choise==2||choise==3);

}void sequencesearch(int *fp,int length)

else

}printf("經過%d次查詢,未能查詢到資料%d.\n",i,data);

}void sort(int *fp,int length)

printf("排序完成!\n下面輸出排序後的陣列:\n");

for(int k=0;k

printf("\n");}

選擇排序演算法的思想是什麼?

2樓:

一、插入排序(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) 當記錄本身資訊量較大時,為避免耗費大量時間移動記錄,可以用連結串列作為儲存結構。

把蘆薈的葉葉掰下來直接插入溼土裡能活嗎

把蘆薈的葉葉掰下來直接插入溼土裡不能成活,因蘆薈不易葉插的,只能葉帶莖一起才能生根發芽。1 扦插繁殖也是蘆薈良種繁殖中常用的一種方法,扦插繁殖與分生繁殖的區別是,分生繁殖是將帶根的完整的蘆薈幼苗植株,從母體上分離下來,進行繁殖。2 扦插繁殖是利用不帶根蘆薈主莖和側枝的下端可以發生不定根的特性,分離繁...

網線直接插入電腦主機就可以上網但是連線TP LINK路由器設定靜態IP後卻不能上網了

上網方式選擇動態ip的上網方式 我的tp link無線路由器的無線網路不能上網,但是用網線連線電腦卻可以上網。具體情況在下面。無線路由沒有配置成功,你登陸上路由器,重新配置一遍即可。或者 回覆一下出廠設定,然後再重新設定一遍。你去你的無線路由器上去設定吧。肯定是無線沒有設定好。我的回答希望對你有幫助...

智慧電視怎麼不通過路由器,直接插入網線能看視

電視可以通過wifi連線網路 可以通過光纖貓直接來連線 可以通過路由器連結網線進行上網 可以通過廣電電視 尊敬的海信使用者,您好!首先對您遇到的問題表示歉意,給您帶來不便,請見諒。根據您的描述可能為網路故障,建議您根據產品使用指南將電視機恢復出廠設定後重新連線網路,並建議您將路由器也恢復出廠觀察使用...