第一章 資料結構導論 結束 2015/6/28 1 本章重點 1-1 認識資料與資訊...

46
第 第第第第第第 第第 110/12/23 1 第第第第 1-1 第第第第第第第 1-2 第第第第第 (Algorithm) 1-3 第第 (program) 第第第第第 (programming) 1-4 第第第第 (Recursion) 1-5 第第第第第第第第

Post on 21-Dec-2015

298 views

Category:

Documents


5 download

TRANSCRIPT

第一章 資料結構導論 結束

112/04/18 1

本章重點

1-1 認識資料與資訊

1-2 解析演算法(Algorithm)

1-3 程式(program)與程式設計(programming)

1-4 遞迴程式 (Recursion)

1-5 演算法的效能分析

第一章 資料結構導論 結束

112/04/18 2

1-1 認識資料與資訊

「資料處理」就是用人力或機器設備,對資料進行有系統的整理如記錄、排序、合併、整合、計算、統計等,以使原始的「資料」符合需求,而成為有用的「資訊」 (Information)

第一章 資料結構導論 結束

112/04/18 3

1-2 解析演算法 (Algorithm) 輸入 (Input) : 0個或多個輸入資料,這些輸入必需有清楚的描述或定義。

輸出 (Output) :至少會有一個輸出結果,不可以沒有輸出結果。

明確性 (Definiteness) :每一個指令或步驟必需是簡潔明確而不含糊的。

有限性 (Finiteness) :在有限的步驟後一定會結束,不會產生無窮迴路。

有效性 (Effectiveness) :步驟清楚且可行,能讓使用者用紙筆計算而求出答案。

第一章 資料結構導論 結束

112/04/18 4

常用的演算法表示方法有 一般文字:中文、英文、數字等。 虛擬語言:接近高階程式語言的寫法,經常使用的有 SP

ARKS 、 PASCAL-LIKE 等語言。 表格或圖形:如陣列、樹狀圖、矩陣圖等。 流程圖:資料流程圖及控制流程圖可以算是一種通用的

表示法,也有固定的圖型符號。 程序語言:目前資料結構的演算法經常是以可讀性高的

高階語言來表示,例如 C語言、 C++ 語言、 Java 語言、Visual Basic 語言等,在本書中將以 C語言來表達演算法

第一章 資料結構導論 結束

112/04/18 5

1-3 程式 (program) 與程式設計 (programming)

需求認識:了解程式所要解決的問題是什麼,有那些輸入及輸出等。

設計規劃:根據需求,選擇適合的資料結構,並以任何的表示方式來寫一個演算法以解決問題。

分析討論:思考其他可能的演算法及資料結構,最後再選出最適當的標的。

編寫程式:把分析的結論,寫成初步的程式碼。 測試檢驗:最後必須確認程式的輸出是否符合需求,

這個步驟得細步的執行程式並進行許多的相關測試。

第一章 資料結構導論 結束

112/04/18 6

程式產生的五階段

第一章 資料結構導論 結束

112/04/18 7

結構化程式設計

它又分為三種基本結構 (Basic Structure) :基本結構名稱 概念圖[ 循序結構 ]逐步的撰寫敘述

[選擇結構 ]依某些條件做邏輯判斷

IF..then..else

[重複結構 ]依某些條件決定是否重複

執行某些敘述

第一章 資料結構導論 結束

112/04/18 8

物件導向程式設計

「物件導向技術」的重要特徵簡述如下: 封裝 (Encapsulation)利用『類別』 (class) 來實作「抽象化資料型態」 (ADT) 。所謂「抽象化」,亦即將代表事物特徵的資料隱藏起來,並定義一些方法來做為操作這些資料的介面,讓使用者只能接觸到這些方法,而無法直接使用資料,符合了「資訊隱藏」 (Information hiding)的真意。

第一章 資料結構導論 結束

112/04/18 9

繼承 (Inheritance)

繼承可分為多重繼承與單一 (或稱個別 )繼承,在繼承關係中,被繼承者稱為『基礎類別』或『父類別』,而繼承者則稱『衍生類別』或『子類別』。當在一個繼承關係中的基礎類別有多個時,即稱『多重繼承』;而若基礎類別只有一個時則稱『單一繼承』。

第一章 資料結構導論 結束

112/04/18 10

[圖例 ]父類別 (汽車 )與子類別 (福特汽車及BMW),皆繼承汽車的速度方法,但福特汽車的速度性能卻與BMW不同。

第一章 資料結構導論 結束

112/04/18 11

資料結構

資料( Data) 電腦處理的符號

數值( Numerical ) 字串( String ) 多媒體( Multimedia )

資料結構( Data Structure) 資料之間的邏輯關係

表現方式( Representation ) 處理方式( Manipulation )

著重問題需求和資料之間的關係

第一章 資料結構導論 結束

112/04/18 12

資料特性

識別( Identification) 順序( Sequential Order) 階層( Hierarchical Structure) 形狀

線性結構( Linear ) 樹狀結構( Tree ) 圖形結構( Graph )

第一章 資料結構導論 結束

112/04/18 13

因為儲存層次上的不同可分為三種:

基本資料型態 (atomic data type) 或稱為實質資料型態 (physical data type)

結構型資料型態 (structure data type)或稱為虛擬資料型態 (virtual data type)

抽象資料型態 (Abstract Data Type : ADT)

第一章 資料結構導論 結束

112/04/18 14

1-4 遞迴程式 (Recursion)

如果一個程式能被自己所定義或呼叫的,就稱為「遞迴程式」。一個遞迴程式必備的兩個要件:

一個可以反覆執行的過程 一個跳出反覆執行過程中的出口

第一章 資料結構導論 結束

112/04/18 15

河內塔問題

有三根木樁,第一根上有 n個盤子,最底層的盤子最大,依序最上層的盤子會愈來愈小。

第一章 資料結構導論 結束

112/04/18 16

我們還要介紹遞迴因為呼叫對象的不同,可以區分為兩種:直接遞迴 (Direct Recursion)指遞迴程序 (procedure)內容中,允許直接呼叫該程序(procedure) 本身,稱為直接遞迴。間接遞迴 (Indirect Recursion)指遞迴程式的內容中,如果呼叫其他遞迴程式,再從其他遞迴程式呼叫回原來的遞迴程式,我們就稱做間接遞迴。

第一章 資料結構導論 結束

112/04/18 17

求算階乘( Factorial)

n! = n*(n-1)*(n-2)*…*2*1 遞迴定義:

1!=1 f(n)=n*f(n-1), n>=2

13! = 1932053504 ,在 32 位元系統上用 long 所能算出的最大階乘數

long fact(int n) { if (n == 1) return 1; else return n * fact(n-1);}

long fact(int n) { if (n == 1) return 1; else return n * fact(n-1);}

第一章 資料結構導論 結束

112/04/18 18

遞迴程式的優缺點

優點:程式簡短,可讀性高,較節省記憶空間

缺點:遞迴程式使用了暫存堆疊與活動記錄表 (activation record) 來記錄程式參數的暫存值及系統資料,所以執行時間較長。

第一章 資料結構導論 結束

112/04/18 19

1-5 演算法的效能分析

在一個完全理想狀態下的計算機中,我

們定義一個 T(n) 來表示程式執行所要花

費的時間,其中 n代表資料輸入量。

第一章 資料結構導論 結束

112/04/18 20

演算法的效率分析

時間複雜度( Time Complexity) 所需的執行時間

Σ 一行敘述的執行次數 × 一行敘述的執行時間 空間複雜度( Space Complexity)

所需的記憶體空間 複雜度的表示法

О 、 Ω 、 Θ

第一章 資料結構導論 結束

112/04/18 21

Big-oh 的介紹

O(f(n)) 可視為某演算法在電腦中所需執行時間不會超過某一常數倍的 f(n) ,也就是說某演算法的執行時間 T(n) 的時間複雜度 (time complexity) 為 O(f(n))( 讀成 big-oh of f(n) 或 order is f(n)) 。

第一章 資料結構導論 結束

112/04/18 22

Big-O 演算法的複雜度

定義:

若且唯若存在兩個正整數 c 和 n0當 n ≥ n0 時,

意義: Upper Bound 上限

)()( ngcnf

)()( ngOnf

第一章 資料結構導論 結束

112/04/18 23

範例: 22 1744 nOn

14

17417445

5

,1744

0

020

20

022

n

nnn

c

nnncn

)(17445174414 2222 nOnnnn 時當

第一章 資料結構導論 結束

112/04/18 24

範例:)()(

)( 011

1

m

mm

mm

nOnf

ananananf

m

ii

m

mim

ii

m

im

ii

m

i

ii

mm

mm

an

nan

na

na

ananananf

0

0

0

0

011

1)(

第一章 資料結構導論 結束

112/04/18 25

時間複雜度分析範例:循序搜尋( Sequential Search)

最佳狀況 Best Case : 1 搜尋目標在陣列一開頭就找到了

最壞狀況 Worst Case : n 找完整個陣列才知搜尋目標不在其中

平均狀況 Average Case : n/2 平均搜尋次數:

若搜尋成功之機率為 p :

2

1

2

)1(121

11

1

nnn

nn

nk

n

n

k

22

1)1(2

)1(1

1

ppnpn

nppn

n

pk

n

k

第一章 資料結構導論 結束

112/04/18 26

循序搜尋( Sequential Search)

int sequential_search(int data[], int target, int n) { int i; for (i = 0; i < n; i++) { if (target == data[i]) { return i; } } return -1;}

int sequential_search(int data[], int target, int n) { int i; for (i = 0; i < n; i++) { if (target == data[i]) { return i; } } return -1;}

第一章 資料結構導論 結束

112/04/18 27

常見的 Big-oh 有下列幾種:

O(1) :稱為常數時間 (constant time) O(log2n) :稱為次線性時間 (sub-linear time) O(n) :稱為線性時間 (linear time) O(n ) :稱為平方時間 (quadratic time) O(n ) :稱為立方時間 (cubic time) O(2 ) :稱為指數時間 (exponential time)

2

3

n

第一章 資料結構導論 結束

112/04/18 28

Ω(omega) 的介紹 Ω也是一種時間複雜度的漸近表示法,如果說 Big-oh 是執行時間量度的最壞情況,那 Ω就是執行時間量度的最好狀況。以下是 Ω的定義:

對 f(n)= Ω(g(n))( 讀作 "big-omega of g(n)") ,意思是存在常數 c 和 n0 ,對所有的 n 值而言, n= n0

時, f(n) =cg(n) 均成立。

第一章 資料結構導論 結束

112/04/18 29

Big-Ω 問題的難易程度

定義:

若且唯若存在兩個正整數 c 和 n0 ,當 n ≥ n0 時,

意義: Lower Bound 下限

)()( ngnf

)()( ngcnf

第一章 資料結構導論 結束

112/04/18 30

範例:

1100

1

1

233

0

nnnn

n

c

1100 233 nnnn

第一章 資料結構導論 結束

112/04/18 31

θ(theta) 的介紹 是一種比 Big-O 與 Ω更精確時間複雜度的漸近表示法。定義如下:

f(n)= θ(g(n))( 讀作“ big-theta of g(n)”) ,意思是存在常數 c1 , c2 , n0 ,對所有的 n ≥ n0 時, c1g(n)f(n)

c2g(n) 均成立。換句話說,當 f(n)= θ(g(n)) 時,就表示 g(n) 可代表 f(n) 的上限與下限。

第一章 資料結構導論 結束

112/04/18 32

Θ 最佳解( Optimal Solution)

定義:

若且唯若存在三個正整數 c1 、 c2 、 n0 ,當 n ≥ n0 時

)()( ngnf

)()()( 21 ngcnfngc

第一章 資料結構導論 結束

112/04/18 33

二元搜尋( Binary Search)

輸入: n 筆已排序資料(從小排到大) 欲尋找之資料 target

輸出: target 於輸入資料中的位置(序號) 如果 target 不在輸入資料中,則傳回 -1

0 1 2 3 4 5 6 7 8 9

找 5

大小

第一章 資料結構導論 結束

112/04/18 34

二元搜尋( Binary Search)

int binary_search(int data[], int n, int target) { int left = 0, right = n-1, mid; while (left <= right) { mid = (left + right) / 2; if (target == data[mid]) { return mid; } else if (target > data[mid]) { left = mid + 1; } else { right = mid - 1; } } return -1;}

int binary_search(int data[], int n, int target) { int left = 0, right = n-1, mid; while (left <= right) { mid = (left + right) / 2; if (target == data[mid]) { return mid; } else if (target > data[mid]) { left = mid + 1; } else { right = mid - 1; } } return -1;}

第一章 資料結構導論 結束

112/04/18 35

二元搜尋( Binary Search)遞迴版( Recursive)

int bin_search(int data[], int left, int right, int target) { int mid = (left + right) / 2; if (left > right) return -1; if (target == data[mid]) return mid; if (target > data[mid]) { return bin_search(data, mid+1, right, target); } else { return bin_search(data, left, mid-1, target); }}

int bin_search(int data[], int left, int right, int target) { int mid = (left + right) / 2; if (left > right) return -1; if (target == data[mid]) return mid; if (target > data[mid]) { return bin_search(data, mid+1, right, target); } else { return bin_search(data, left, mid-1, target); }}

用法: bin_search(data, 0, n-1, target)

第一章 資料結構導論 結束

112/04/18 36

二元搜尋( Binary Search)

時間複雜度: O(log n) 搜尋範圍從 n 筆資料開始 每完成一次比較,搜尋範圍縮小一半 停止的時機:

找到目標 搜尋範圍的大小 <1 ( Worst Case ) n 連續除以 2 ,連除 m 次之後 < 1

nm

n m

2log

2

第一章 資料結構導論 結束

112/04/18 37

費氏數列( Fibonacci Series)

2,

1

0

21

1

0

nfff

f

f

nnn

問題:給定一個 n 值,求解費氏數列第 n 項的值。

第一章 資料結構導論 結束

112/04/18 38

費氏數列( Fibonacci Series)遞迴版

int fibon(int n) { if (n == 0) return 0; if (n == 1) return 1; return fibon(n-1) + fibon(n-2);}

int fibon(int n) { if (n == 0) return 0; if (n == 1) return 1; return fibon(n-1) + fibon(n-2);}

時間複雜度: O(2n/2)

第一章 資料結構導論 結束

112/04/18 39

費氏數列( Fibonacci Series)遞迴版時間複雜度分析

nn

n

nnn

nn

nnn

ccf

r

rr

rrr

rf

fff

2

51

2

51

2

51,

2

51

01

0

21

2

21

21

nn

nf

cc

ccf

ccf

2

51

2

51

5

1

5

1,

5

1解得

12

51

2

51

02

51

2

51

21

1

2

1

11

0

2

0

10

第一章 資料結構導論 結束

112/04/18 40

費氏數列( Fibonacci Series)迴圈版

int fibonacci(int n) { int fn, fn_1 = 1, fn_2 = 0, i; if (n < 2) return n; for (i = 2; i <= n; i++) { fn = fn_1 + fn_2; fn_2 = fn_1; fn_1 = fn; } return fn;}

int fibonacci(int n) { int fn, fn_1 = 1, fn_2 = 0, i; if (n < 2) return n; for (i = 2; i <= n; i++) { fn = fn_1 + fn_2; fn_2 = fn_1; fn_1 = fn; } return fn;}

時間複雜度: O(n)

第一章 資料結構導論 結束

112/04/18 41

Tower of Hanoi

第一章 資料結構導論 結束

112/04/18 42

Tower of Hanoi

第一章 資料結構導論 結束

112/04/18 43

Tower of Hanoi 宣告與用法

#define PEG_A "PEG_A"#define PEG_B "PEG_B"#define PEG_C "PEG_C"

int main(int argc, char* argv[]){ … hanoi_move(n, PEG_A, PEG_B, PEG_C); …}

第一章 資料結構導論 結束

112/04/18 44

Tower of Hanoi 主要邏輯

void hanoi_move(int n, char* from, char* to, char* via) { if (n == 1) { printf("Move ring 1 from %s to %s\n", from, to); } else { hanoi_move(n-1, from, via, to); printf("Move ring %d from %s to %s\n", n, from, to); hanoi_move(n-1, via, to, from); }}

第一章 資料結構導論 結束

112/04/18 45

Tower of Hanoi 執行結果

1: Move ring 1 from PEG_A to PEG_B 2: Move ring 2 from PEG_A to PEG_C 3: Move ring 1 from PEG_B to PEG_C 4: Move ring 3 from PEG_A to PEG_B 5: Move ring 1 from PEG_C to PEG_A 6: Move ring 2 from PEG_C to PEG_B 7: Move ring 1 from PEG_A to PEG_B

第一章 資料結構導論 結束

112/04/18 46

Tower of Hanoi時間複雜度分析