• 沒有找到結果。

搜尋與排序

N/A
N/A
Protected

Academic year: 2021

Share "搜尋與排序"

Copied!
30
0
0

加載中.... (立即查看全文)

全文

(1)

講師:洪安

搜尋與排序

Search and Sort

1

(2)

排序與搜尋

 搜尋

循序(線性)搜尋法(Linear Search)

二分搜尋法(Binary Search)

 排序

氣泡排序法(Bubble Sort)

選擇排序法(Selection Sort)

插入排序法(Insertion Sort)

快速排序法(Quick Sort)

(3)

排序

 簡介

將一群資料按照某一規則排列,使其具有遞增(減)

的線性關係

 分類與比較

執行效率

記憶體空間

穩定性

 用途

資料搜尋

進階的分析與處理

5 1 4 2 3

sort

1 2 3 4 5

3

(4)

選擇排序法 Selection Sort

在一段資料中找出最大(小)值後,才做交換

範例程式碼(將資料由小排到大)

int i, j, tmp, min;

int n[5] = {7,1,3,9,5}; // 欲排序的資料 for( i=0; i<4; i++) {

min = i;

for( j=i+1; j<=4; j++) // 找出最小值 if(n[ j] < n[min])

min = j;

// 把最小值跟第 i 個做交換 if (min != i) {

tmp = n[i];

n[i] = n[min];

n[min] = tmp;

}

7 1 3 9 5

i=0, j=2, min是1, n[1]=1

7 1 3 9 5

i=0, j=3 , min是1, n[1]=1

7 1 3 9 5

i=0, j=4 , min是1, n[1]=1

1 7 3 9 5

i=0, j=4 , 把min換到最前面

7 1 3 9 5

i=0, j=1, min是1, n[1]=1

1 7 3 9 5

i=1, j=2

1

1

1

1 1

7

min

……

i=0, min是0, n[0]=7

(5)

 操作範例

選擇排序法 Selection Sort

 特點

當資料紀錄很大 (欄位 數多) ,比較之鍵值是 少量的,則適合

Selection Sort

因為每個回合至多一次 交換動作

5

7 1 3 9 5

1 7 3 9 5

1 3 7 9 5

1 3 5 9 7

1 3 5 7 9

(6)

課堂練習

 以下為一個動態的”選擇排序法”程式,請用迴圈 讓使用者輸入6次數字,然後將每次排序的結果輸 出:

 輸出輸入範例如下:

第一次輸入:9;輸出:9

第二次輸入:3;輸出:3 9

第三次輸入:7;輸出:3 7 9

第四次輸入:5;輸出:3 5 7 9

第五次輸入:9;輸出:3 5 7 9 9

第六次輸入:2;輸出:2 3 5 7 9 9

程式結束

Ans: 9_SelectionSort.cpp

(7)

插入排序法 Insertion Sort

將一段資料中最右(左)邊的資料當作key,然後往左(右) 塞入此資料中作排序

範例程式碼(將資料由小排到大)

7

int i, j, key;

int n[5] = {7,1,3,9,5}; // 欲排序的資料 for( i=1; i<=4; i++) {

key=n[i];

for( j=i-1; j>=0 && n[ j]>key; j--) n[j+1] = n[ j];

n[ j+1] = key;

}

1 7 3 9 5

i=2, j=1

1 3 7 9 5

i=2, j=0

1 3 7 9 5

i=3, j=2, 9比7大,不必排

1 3 7 9 5

i=4, j=3

7 1 3 9 5

i=1, j=0

1 3 5 7 9

i=4, j=1

已排好的 目前的

……

(8)

課堂練習

 以下為一個動態的”插入排序法”程式,請用迴圈 讓使用者輸入6次數字,然後將每次排序的結果輸 出:

 輸出輸入範例如下:

第一次輸入:9;輸出:9

第二次輸入:3;輸出:3 9

第三次輸入:7;輸出:3 7 9

第四次輸入:5;輸出:3 5 7 9

第五次輸入:9;輸出:3 5 7 9 9

第六次輸入:2;輸出:2 3 5 7 9 9

程式結束

Ans: 9_InsertionSort.cpp

(9)

氣泡排序法 Bubble Sort

 排序時,最大的元素會如同氣泡一樣移至右端

 利用比較相鄰元素的方法,將大的元素交換至右端

 口訣:小在前,大在後!

9

(10)

操作範例 (1/2)

10 7 13 5 1

比較10> 7 ,10和7對調

7 10 13 5 1

比較10<= 13 ,不做任何事

7 10 13 5 1

比較13>5 , 13和5對調

(11)

比較13> 1 ,13和1對掉

7 10 5 13 1

最後結果: 最大的數跑到最右邊了

7 10 5 1

比較7<=10 ,不做任何事

13

剩下4個數還未排序,重複剛才的動作,這次讓10跑到右邊

操作範例 (2/2)

7 10 5 1 13

11

(12)

完整操作範例

10,7,13,5,1 由小到大排列

Step1.1 10>7,於是兩者交換,陣列變成7,10,13,5,1

Step1.2 10<13,於是沒有動作

Step1.3 13>5,於是兩者交換,陣列變成7,10,5,13,1

Step1.4 13>1,於是兩者交換,陣列變成7,10,5,1,13

到此為止,我們已經把最大的元素13移至最右端了,下一次只需檢查到陣列倒 數第二個元素即可。

Step2.1 7<10,於是沒有動作

Step2.2 10>5,於是兩者交換,陣列變成7,5,10,1,13

Step2.3 10>1,於是兩者交換,陣列變成7,5,1,10,13

第二大的元素10也就定位了。

Step3.1 7>5,於是兩者交換,陣列變成5,7,1,10,13

Step3.2 7>1,於是兩者交換,陣列變成5,1,7,10,13

第三大的元素7也就定位了。

Step4.1 5>1,於是兩者交換,陣列變成1,5,7,10,13

完成。

(13)

課堂練習

 請利用氣泡排序法程式片段,撰寫一個程式可以讓 使用者任意輸入5個數字,程式會輸出排序結果

13

(14)

課堂練習

 請參考 9_bubblesort.cpp ,將其修改為使用樣板 (Template)的版本

Ans: 9_bubblesort_template.cpp

(15)

快速排序法 Quick Sort (1/4)

 平均情況下執行時間最快的方法

 採取 Divide and Conquer 策略

 觀念1

每回合處理之後,pk會被放置正確位子

15

1

2 3 n

Pivot Key

1 2

3

n

Pivot Key

比Pivot Key小 比Pivot Key大

Divide!

(16)

快速排序法 Quick Sort (2/4)

 觀念2

分為左右半部後

各自做遞迴 quick sort

 如何決定 pk 之正確位置?

作法

Conquer!

1 2 3 4 5 6 7 8 9 10

26 5 37 1 61 11 59 48 39 65

i : 找>=pk j : 找<=pk

i i:找到37>=26 j: 找到 11 <= 26 j

(17)

快速排序法 Quick Sort (3/4)

資料結構與C++程式設計進階班 17

1 2 3 4 5 6 7 8 9 10

26 5 11 1 61 37 59 48 39 65

j: 找到 1 <= 26

i:找到61>=26 i 和 j 擦身而過,所以 pk正確位置應該是4

1 2 3 4 5 6 7 8 9 10

1 5 11 26 61 37 59 48 39 65

swap

(18)

快速排序法 Quick Sort (4/4)

 演算法:

 最好與平均情況

nlogn

 最差情況

n2

發生在資料由小 到大或由大到小 的情況

i : 找>=pk

j : 找<=pk

sort左半邊 sort右半邊

(19)

排序法的比較

執行效率(Computational Complexity)

速度:排序一群資料所需的”比較”次數

例如:氣泡排序法排序 N 筆資料需比較次數為為 (N- 1)x(N-2)/2

記憶體空間(Memory Usage)

排序一群資料所需要的記憶體空間

例如:快速排序法排序N筆資料通常需 logN 的額外記憶 體空間

穩定性(Stability)

對於鍵值相同的資料其”原始順序”排序後能否被保留?

If Yes:穩定

If No:不穩定

19

(20)

分類與比較一覽表

 同樣排序 n 筆資料

Bubble Selection Insertion Quick

平均情形 O(n2) O(n2) O(n+d) O(nlogn)

最糟情形 O(n2) O(n2) O(n2) O(n2)

記憶體使用 O(1) O(1) O(1) O(logn)~O(n)

穩定性 Y Y Y N

備註 (需交換)的d是相反資料

個數

(21)

排序與搜尋

 搜尋

循序搜尋法(Linear Search)

二分搜尋法(Binary Search)

 排序

氣泡排序法(Bubble Sort)

選擇排序法(Selection Sort)

插入排序法(Insertion Sort)

快速排序法(Quick Sort)

21

(22)

循序(線性)搜尋法 Linear Search

 在一群資料中,從頭搜尋到尾直到找到資料為止

 又稱 Sequential Search

 範例程式碼

int linearSearch(int key) {

int n[10] = {-2,0,1,2,3,4,6,7,9,14}, key=3;

int found = -1;

for( i=0; i< 10; i++) if(n[i] == key) {

found=i;

break;

}

return found;

• 實施之前,紀錄不需事先排序過

• 可用隨機存取 (Array) 或循序存 取 (Linked List) 方式支援

輸出

1. 大 於 等 於 0 表示找到第 i筆符合key 值

2. 等於-1表示 沒找到

(23)

二元搜尋法 Binary Search

 在已排序的資料數列中尋找某一筆資料

 須藉助隨機存取 (Array) 機制支援

 在執行二元搜尋時的比較,可以分成三種情況,如 下所示:

搜尋鍵值小於陣列的中間元素

鍵值在資料陣列的前半部

搜尋鍵值大於陣列的中間元素

鍵值在資料陣列的後半部

搜尋鍵值等於陣列的中間元素

找到搜尋的鍵值

23

小 → 大

中間元素

(24)

1 5 9 12 16

Num

Num[0] Num[1] Num[2] Num[3] Num[4]

Up

↓ Low

int SearchKey=7; //數字7在陣列裡的哪個位置 (0~4) int Low=0,Up=4;

int Middle=(Up+Low)/2; // (0+4)/2 = 2 Middle

操作範例 (1/4)

(25)

1 5

9 12 16

Num

Num[0] Num[1] Num[2] Num[3] Num[4]

Up

↓ Low

//因為: 7不在Num[middle], 且7<9

//所以: 我們知道7如果在陣列裡的話,應該會在middle 的左邊 // => 把up移到middle-1的位置 Up=Middle-1;

//把Up移到新的位置後,計算新的middle

middle=(Up+Low)/2; // middle = (0+1)/2 =0 Middle

操作範例 (2/4)

25

(26)

1

5

9 12 16

Num

Num[0] Num[1] Num[2] Num[3] Num[4]

Up

↓ Low

//因為: 7 不在Num[middle], 且7>1

//所以: 我們知道7如果在陣列裡的話,應該會在middle 的右邊 // => 把Low移到middle+1的位置 Low=Middle+1;

//把Low移到新的位置後,計算新的middle Middle

操作範例 (3/4)

(27)

1 5 9 12 16

Num

Num[0] Num[1] Num[2] Num[3] Num[4]

Up

Low

//因為: 7 不在Num[middle], 且7>5

//所以: 我們知道7如果在陣列裡的話,應該會在middle 的右邊 // => 把Low移到middle+1的位置 Low=Middle+1;

//把Low移到新的位置後,發現Low > Up //告知使用者7不在陣列裡

Middle

操作範例 (4/4)

27

(28)

程式範例

// bool done;

// bool 這個資料型態只能有兩個值 true, false // !false==true

//!true==false

(29)

課堂練習

 請改寫上面所給的二元搜尋法 C 程式片段,撰寫 一個 C++ 程式可以讓使用者任意輸入5個數字並 指定一個任意的搜尋數字,程式會輸出搜尋結果

29

(30)

搜尋法比較

 循序搜尋法

資料不需排序

易實作、但效率較低

 二元搜尋法

容易實作、效率高

必須確保資料有經過排序

參考文獻

相關文件

z請利用 struct 記錄 Bob 和 Alice 的相關資訊 z列印出 Bob 及 Alice 分別花多少錢. z再列印出

private void closeBTN_Click(object sender, System.EventArgs

zCount 屬性–取得項目個數 zAdd 方法–新增項目. zRemove 方法–移除指定項目

private void answerLB Click(object sender private void answerLB_Click(object sender,. System.EventArgs

此行文字的特別意義,是讓 MATLAB 藉由 lookfor 指令 搜尋並顯示此函式用途。.. 語法:

單一菜色與地區搜尋 ( 兩種二選一 ) 交叉搜尋 (4 種可同時 )/QR 碼搜尋.

簡報裡展現一枚以拉斐爾的名畫一角做成的郵 票。 請搜尋這幅畫的全貌,並模仿美術館導覽

1.學生體驗Start on tap、一個角色同 時可觸發多於一 個程序及經歷運 用解決問題六步 驟編寫及測試程 序.