1 / 26

第一章

第一章. Introduction. 導論. 1 -1 資料與資訊. 資料 ( data ) 的定義:〝用具體符號表示,而能夠被計算機處理的資訊 ( information)〞 。 資料強調符號本身,而資訊則強調資料所呈現出來,經過人們分析、理解並領會的事實。 我們將在資料結構這門課中探討計算機系統所儲存以及處理的資料,並且學習如何組織這些資料,及處理這些資料的方法。. c 語言的基本資料型態有: int: 整數( Integer ) 16-bit, int i=2; long int: 長型整數( Integer ) 32-bit

joel-foster
Télécharger la présentation

第一章

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第一章 Introduction 導論

  2. 1-1 資料與資訊 • 資料 ( data ) 的定義:〝用具體符號表示,而能夠被計算機處理的資訊 (information)〞。 • 資料強調符號本身,而資訊則強調資料所呈現出來,經過人們分析、理解並領會的事實。 • 我們將在資料結構這門課中探討計算機系統所儲存以及處理的資料,並且學習如何組織這些資料,及處理這些資料的方法。

  3. c 語言的基本資料型態有: • int: 整數(Integer)16-bit, int i=2; • long int: 長型整數(Integer) 32-bit • float:單精確度浮點數 (Floating Point) 32-bit • double:雙精確度浮點數(Floating Point) 64-bit • char: 字元(Character ) 8-bit, char c='c'; • bool: 布林(Boolean) 1-bit • c 語言的組合資料型態有: • 陣列型態: char c[5] = { 'a', 'b', 'c', 'd', 'e' } • 結構型態: struct score { int math; int computer; } horng, chang;

  4. 1-2演算法與資料結構 • 資料結構這門課就是研究資料在記憶空間中的儲存方式,以便我們在設計程式處理問題時,能使用最佳的資料結構,並提供一種策略或方法能有效率的善用這些資料,以達到下列目的: • 執行程式速度快。 • 資料佔用最少的記憶空間。 • 更快速的存取這歇資料。 • 能有效率將這些資料轉換成有用的資訊的策略或方法就是 演算法 (algorithm) 。 • 演算法 + 資料結構 = 程式 方法策略 資料 資訊

  5. 1-2 資料結構與演算法 • 演算法 (algorithm) 的定義:“在有限步驟內解決數學問題的程序”。在計算機科學的領域中,演算法泛指“適合被實作為計算機程式的解題方法” • 演算法通常具有以下五個特性: 1‧輸入 (Input) 2‧輸出 (Output) 3‧明確性 (Definiteness) 4‧有限性 (Finiteness) 5‧正確性 (Correctness)或稱 有效性 (Effectiveness) • 演算法表達方法: 1‧一般的語言 2‧虛擬碼 3‧流程圖

  6. 例 歐幾里得演算法 計算兩個自然數的最大公因數 (Greatest Common Divisor, GCD) 演算法描述如下: 步驟 1. 輸入兩個自然數 A , B 步驟 2.A 除以B,餘數為 R 步驟 3.如果 R 為零,則跳至步驟 5 步驟 4. A←B,B←R,跳至步驟 2 步驟 5. B 即為 GCD

  7. 這些敘述符合演算法的特性: 一‧輸入 (Input) :兩個自然數 A, B 。 二‧明確性 (Definiteness):以逐步追蹤法 一步一步執行敘述,不造成混淆。 三‧正確性 (Correctness):以兩組 A, B 代入執行均得到正確結果。 四‧有限性 (Finiteness): A, B, R 在第二圈以後都會愈來愈小(因為每一圈 R 一定小於 B)。由於他們都是正整數,所以 R 終會等於零。 五‧輸出 (Output) :A, B 的最大公因數。

  8. 用流程圖來描述這個演算法:  開 始  輸入自然數A,B  R = A MOD B 否 A ← B B ← R   R = 0 ? 是  B為GCD  結 束

  9. 1-3 程式的分析 一個好的程式,通常必須滿足下列的條件: 一‧正確達到目的:通常以具有代表性的多組輸入來測試驗證 二‧可維護性高:程式的可維護性牽涉到編寫程式的方法和風格,以下是幾項檢驗項目:   檢驗項目一:編寫程式是否符合模組化的原則,提供由上而下 (Top-Down)的理解思路? 檢驗項目二:所有的常數變數及函式 (function) 名稱是否有意義? 檢驗項目三:所有函式的輸入、輸出及功能是否被明確地定義? 檢驗項目四:是否在適當的地方加上註解? 檢驗項目五:說明文件是否詳實完備? 三‧效率高:計算程式的時間複雜度來分析效率並尋求改良之道 四‧記憶體需求低:在不影響效率的情況下,需求愈低愈好

  10. 1-4 執行效率 一、C指令的執行步數 • 註釋: 0步. • 宣告指令: 0步. 例: int a[100]; • 運算式Expressions和指定指令 • <variable> = <expr> • 通常1步, 除了包括函式呼叫, 例: i++; a = b; 1步. d = get_key(a[i],pass,m); ?步, 由函式決定。 • 變數陣列<variable>由陣列大小決定。 例: int a[100], b[100]; 指定指令 a = b, 為100步.

  11. C 指令的執行步數 • Switch指令 • 每一條件步數condition就是自己的成本加上所有的前面條件步數再加上<expr>的步數。 Switch (<expr>) { case cond1: <statement1> case cond2: <statement2> . . . default: <statement> } • if-else指令 if (<expr>) <statement1>; else <statement2>; • 計算if-else指令的執行步數由<expr>, <statement1>, 和 <statement2>決定。

  12. C 指令的執行步數 • 函式步數: 通常1步, 除非包括有pass-by-value之參數傳遞及遞迴呼叫recursive invocation 之函式。 • 函式指令步數: void main( ) : 0步。 • 記憶體管理指令步數: malloc, free, sizeof : 1步。 • 跳躍指令步數: continue, break, goto, return : 1步。 return <expr>的執行步數由<expr>決定。 • I/O指令步數: printf, scanf: 1步。

  13. 二、計算執行步數的方法 • 在程式中加入count變數 • 例: 2n + 3 steps. // O(n) float sum (float *a, const int n) {float s = 0 ; count++ ; // count is global for (int i = 0; i< n; i++) { count++ ; // for for s += a[i] ; count++ ; // for assignment } count++ ; // for last time of for count++ ; // for return ; return s ; }

  14. 三、 while 迴圈的計數 計算 n 階層 ( n! ) 的函式如下: int factor( int n) { int result, i ; 1result = 1 ; 2                  i = 1 ; 3                  while ( i < = n ) 4                  { 5                 result = result * i ; 6                  i = i + 1 ; 7                  } 8                  return result; }

  15. 行號 n>0 時 n <= 0 時 1 1 1 2 1 1 3 n+1 1 5 n 0 6 n 0 8 1 1 總次數 3n+4 4 我們計算每一行敘述被執行的次數: 如果 n>0,頻率計數為 3n+4次,如果 n <= 0 ,頻率計數為 4次

  16. 四、計算第n項之費氏級數f(n)的函式如下: • f(n) = f(n-1) + f(n-2), n >=2; f(0) = 0, f(1) = 1; • #include <stdio.h> • void main( ) • { int n, i, fn1, fn2, fn; • printf( "請輸入費氏級數的項數n ==> " ); • scanf( "%d", &n); • if (n <= 1) printf ( "[%d] \n", n); • else • { fn1=1; fn2=0; • printf ( "[0][1]"); • for ( i=2; i<=n; i++ ) • { fn = fn2 + fn1; • printf ( "[%d]", fn); • fn2 = fn1; • fn1 = fn; } • printf ( "\n"); } • }

  17. #include <stdio.h> • void main( ) • { int n, i, fn1, fn2, fn; • printf("請輸入費氏級數的項數n==>"); • scanf( "%d", &n); • if (n <= 1) printf ( "[%d] \n", n); • else • { fn1 = 1; fn2 = 0; • printf ( "[0][1]"); • for ( i=2; i<=n; i++ ) • { fn = fn2 + fn1; • printf ( "[%d]", fn); • fn2 = fn1; • fn1 = fn; } • printf ( "\n"); } • } 如果n>1,頻率計數為 5n+7次,如果 n<=1,頻率計數為 4 次

  18. 五、 for迴圈的計數 A. 單層迴圈 1for ( i = 1 ; i < n ; i++) 2 result = result + 1 ; 我們計算每一行敘述被執行的次數: 行號 1: 條件成立 (if i < n ),頻率計數為 n-1次,條件不成立(if i = n ), 頻率計數為 1次; 總執行的次數為 n次。 行號 2: 迴圈計數器i的範圍是1…n-1,因此迴圈共重複 n-1 次, 總執行的次數為 n-1次。 簡單的數學模式: n-1 總次數 = Σ 1 = n-1 i=1

  19. B. 雙層迴圈、內圈固定次數 1          for ( i = 0 ; i < n ; i++) 2 for ( j = 1 ; j < n ; j++) 3 result = result + 1 ; 我們計算每一行敘述被執行的次數: 行號 1: 條件成立 (if i < n ),頻率計數為 n 次,條件不成立(if i = n ), 頻率計數為 1 次; 總執行的次數為 n+1 次。 行號 2: 迴圈計數器 j 的範圍是1…n-1,因此,迴圈條件成立共執行 n*(n-1) 次,迴圈條件不成立共 n 次,總執行的次數為 n*(n-1) + n 次。 行號 3: 外圈迴圈計數器 i 的範圍是 0…n-1,內圈迴圈計數器 j 的範圍是 1…n-1,外圈每執行1圈,內圈就會執行 n-1 圈。而外圈會執行 n 圈,因此,第 3 行敘述共將執行 n * (n-1) 次。

  20. C. 雙層迴圈、內圈不固定次數 1for ( i = 1 ; i < = n ; i++) 2 for ( j = i+1 ; i <= n ; j++) 3 result = result + 1 ; 我們計算每一行敘述被執行的次數: 行號 1: 條件成立 (如果 i <= n ),頻率計數為 n 次, 條件不成立(如果 i = n+1 ),頻率計數為 1 次; 總執行的次數為 n+1 次。 行號 2: 迴圈計數器 j 的範圍是 i + 1,…, n,( i =1, 2, ..., n; j = 2, 3, 4, ..., n), 因此,迴圈條件成立共執行 (n-1)+(n-2) + ... + 3 + 2 +1 + 0 = n * ( n-1 ) / 2 次, 迴圈條件不成立共 n 次,總執行的次數為 n*(n-1) + n 次。 行號 3: 第 3 行敘述共將執行 n * (n-1) / 2 次。

  21. i 的值 j 的範圍 第3行執行次數 1 2 …… n n-1 2 3 …… n n-2 3 4 …… n n-3 … … n-1 n …… n 1 n n+1 …… n 0 總次數 = n * ( n-1 ) / 2 數學模式: n n-1 n n 總次數=ΣΣ1 = Σ( n-1-(i+1)+1) = Σ(n –i)= n2-n*(n+1)/2 = n*(n-1)/2 i=1j=i+1 i=1 i=1

  22. 六、Big-O符號 Big-O符號的數學定義為:若且唯若 f(n) = O(g(n)) 則存在大於 0 的常數 c 和 n0,使得對所有的 n 值,當n ≧ n0時,f(n) ≦ c * g(n) 均成立。 用數學式表示為: f(n) = O(g(n))  c, n0>0  n≧ n0 , f (n) ≦ c * g(n) 用口語解釋為:f(n) 取Big-O符號為O( g(n)),當 n 夠大的時候,g(n)相當 於是f(n)的上限  c*g(n) 用圖示可表達為: f(n) n n0

  23. ◎ 5n2 + 6n + 9 = O( n2 ) → f( n ) = 5n2 + 6n + 9, g( n ) = n2 → f 函數取Big-O符號為 g函數 →5n2 + 6n + 9 取 Big-O 符號為 O( n2 ) ◎ 3n lgn + 9n + 10 = O( nlgn ) ,因為 n lgn 的次數比n 大,取最高次項而不計係數時,自然取到 n lgn (lg n = log2n) ◎ 9 n2 + 6nlgn + 9 = O( n2 ) ,因為n2的次數最大,取最高次項而不計係數時,自然取到n2 ◎19n3 + 9 n2 + 6n+ 9 = O( n3 ) ,因為n3的次數最大,取最高次項而不計係數時,自然取到 n3

  24. 常見的時間複雜度等級有: • O(1):常數級 • O(lgn) :對數級 •   O(n) :線性級 •   O(nlogn) •   O(n2) :平方級 •   O(n3) :立方級 •   O(2n) :指數級 • 它們的成長速度順序是: • O(1) < O(logn) < O(n) < O(nlogn) < O(n2) < O(n3) < O(2n) • 如果解決同樣問題的三個程式,他們的時間複雜度分別是O( n2 )、O( nlogn )、O( n3 ),時間複雜度為O( nlogn )的程式是比較有效率的。這就是概略分級的意義,使我們能簡單比較程式的效率。

  25. 常見演算法複雜度:O(1)、O(log n)、O(n)、 O(nlog n)、O(n2)、O(n3)、O(2 n) 、O(n!) 、O(n n) • 1年有31.536百萬秒。

  26. 2106 2n n3 n2 6000 nlogn 1000 n 10 logn 1 2 4 8 16 32 64 128

More Related