430 likes | 1.19k Views
Data Structure ( 資料結構). Assistant Prof. Chih-Chia Yao (姚志佳) E-mail: ccyao@cyut.edu.tw. 教科書 & 參考書目. 教科書 (Textbook) : 基礎資料結構 - 使用 C++, 第二版 , 戴顯權譯 , 開發圖書
E N D
Data Structure (資料結構) Assistant Prof. Chih-Chia Yao(姚志佳) E-mail: ccyao@cyut.edu.tw C. –C. Yao
教科書 & 參考書目 教科書(Textbook): • 基礎資料結構-使用C++, 第二版, 戴顯權譯, 開發圖書 • (原文版) Ellis Horowitz, Sartaj Sahni, and Dinesh P. Mehta, “Fundamentals of Data Structures in C++”, 2nd Ed., Silicon Press, 2007. (開發圖書代理) 參考書目(Reference Books): • Ellis Horowitz, Sartaj Sahni, and Susan Anderson-Freed, “Fundamentals of Data Structures in C”, 2nd Ed., Silicon Press, 2008. (開發圖書代理) • 廖榮貴工作室,“資料結構與演算法”,文魁資訊股份有限公司. C. –C. Yao
成績計算方式 1. 作業: 10% 2. 3次期中考(Midterm Exams): 90% 3. 課程參與(Participation): 10% C. –C. Yao
Chap 1 Basic Concepts (基本概念) C. –C. Yao
演算法(Algorithm) • 定義:演算法是一組有限的指令,根據這些指令可以完成一項特定的工作。所有演算法必須符合以下的條件: • 輸入:可以沒有或從外部提供多個資料. • 輸出:至少產生一個結果. • 明確的:每一個指令都很明白且沒有混淆不清. • 有限的:在所有的情況下,演算法會在有限的步驟之後停止. • 有效率的:每一個指令都可以被執行. C. –C. Yao
Selection Sort • 假設我們要發展一個可以將一組n個整數排序的程式, n ≥ 1. From those integers that are currently unsorted, find the smallest and place it next in the sorted list. • 上述敘述呈現的問題 • 未告知原始的整數儲存在何處,以及以何種方式儲存. • 未告知結果應儲存在何處. C. –C. Yao
C++ Program for Selection Sort voidsort (int *a, const intn) // sort the n integers a[0] to a[n-1] into non-decreasing order for (inti = 0; i < n; i++) { intj = i; // find smallest integer in a[i] to a[n-1] for (intk = i + 1; k < n; k++) if (a[k] < a[j]) j = k; // interchange inttemp = a[i]; a[i] = a[j]; a[j] = temp; } } C. –C. Yao
Selection Sort (Cont.) • 定理 1.1: 函數sort(a, n) 可正確將一組n個整數排序, n ≥ 1; 其結果儲存在a[0] … a[n-1], 使得a[0] ≤ a[1] ≤ … ≤ a[n–1]. C. –C. Yao
Binary Search • 假設有n個不同的整數, n ≥ 1。這些整數已經排序並儲存在陣列中。亦即a[0] ≤ a[1] ≤ … ≤ a[n–1]. 我們必須指出x是否在此串列中。如果在的話傳回j, 使得x = a[j]; 否則傳回 -1. 因為這個串列已經排序, 我們可以使用下列方式來找尋指定的值: 令left和right分別代表所要搜尋的串列之左端和右端。。一開始設定left = 0,right = n – 1. 令middle = (left + right) / 2 為串列的中央位置. 比較a[middle] 以及x, 可以獲得下列三種結果之一: (1) x < a[middle]. 在此情況下如果x出現在串列中, 它一定出現在 0 與middle – 1 之間的位置上. 因此將right 設定為middle – 1. (2) x == a[middle].在此情況下傳回middle. (3) x > a[middle].在此情況下如果x出現在串列中, 它一定出現在middle+1 與n - 1 之間的位置上. 因此將left 設定為middle + 1. C. –C. Yao
Algorithm for Binary Search intBinarySearch (int *a, const intx, const intn) // Search the sorted array a[0], … , a[n-1] for x { for (initialize left and right; while there are more elements;) { let middle be the middle element; switch (compare (x, a[middle])) { case ‘>’: set left to middle+1; break; case ‘<‘: set right to middle -1; break; case ‘=‘: found x; } // end of switch } // end of for not found; } // end of BinarySearch C. –C. Yao
C++ Program for Binary Search char compare (int x, int y) { if (x > y) return ‘>’; else if ( x < y) return ‘<‘; else return ‘=‘; } // end of compare C. –C. Yao
Algorithm for Binary Search (Cont.) intBinarySearch (int *a, const intx, const intn) // Search the sorted array a[0], … , a[n-1] for x { for (intleft = 0, right = n - 1; left <= right;) { intmiddle = (left + right) / 2; switch (compare (x, a[middle])) { case ‘>’: left = middle+1; break; // x > a[middle] case ‘<‘: right = middle -1; break; // x < a[middle] case ‘=‘: returnmiddle; // x == a[middle] } // end of switch } // end of for return -1; } // end of BinarySearch C. –C. Yao
Recursive Algorithms Recursive Relation for and while loop sum=0; sum=0; for (i=1; i<=10; i++) i=1; sum = sum+i; while (i<=10){ sum=sum+i; i++; } printf(“%d”, sum); printf(“%d”, sum); C. –C. Yao
Recursive Algorithms(cont.) Recursive Relation (Cont.) for迴圈可利用sum存放1+2+…+k的值,由 i 來控制 k,其推演方法如下: C. –C. Yao
Recursive Algorithms(cont.) Recursive program: int main() { int n=10; printf(“%d”, rfib(n)); } int rfib(int n) { if (n==1 || n==2) return 1; return rfib(n1)+rfib(n2); } C. –C. Yao
Performance Analysis • 空間複雜度:一個程式的空間複雜度指的是完成這程式所需要的記憶體大小. • 時間複雜度:時間複雜度指的是完成這程式所需要花的時間. C. –C. Yao
空間複雜度 • 跟輸入輸出特性無關的固定部分。這個部分通常包含了指令空間、 簡單變數所佔用的空間、 固定大小的變數所佔用的空間、 以及存放常數的空間. • 變動的部分, 包括不同的輸入可能需要不同的變數數量、 參照變數所需要的空間、 以及遞迴所需的堆疊空間等. • 任何一個程式 P 所需要的空間 S(P) 可以寫成 S(P) = c +Sp ,其中c是一個常數. C. –C. Yao
時間複雜度 • 程式P所需要花的時間 T(P), 是編譯時間和執行時間的和. 編譯時間跟實際資料無關. 我們注重的是程式執行時所需要花的時間, 用 tp 來表示. C. –C. Yao
Time Complexity in C++ • General statements in a C++ program Step count • Comments 0 • Declarative statements 0 • Expressions and assignment statements 1 • Iteration statements N • Switch statement N • If-else statement N • Function invocation 1 or N • Memory management statements 1 or N • Function statements 0 • Jump statements 1 or N C. –C. Yao
Time Complexity Iterative Example floatsum (float *a, const int n) { float s = 0; for (int i = 0; i < n; i++) s += a[i]; return; } C. –C. Yao
Step Count of Iterative Example floatsum (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; } C. –C. Yao
Step Count of Iterative Example (Simplified) void sum (float *a, const int n) { for (int i = 0; i < n; i++) count += 2; count +=3; } If initially count = 0, then the total of steps is 2n + 3. C. –C. Yao
Time Complexity of Recursive Example float rsum (float *a, const int n) { if (n <= 0) return 0; else return (rsum(a, n–1) + a[n-1]); } C. –C. Yao
Step Count of Recursive Example float rsum (float *a, const int n) { count++; // for if conditional if (n <= 0) { count++; // for return return 0; } else { count++; // for return return (rsum(a, n–1) + a[n-1]); } } Assume trsum(0) = 2 trsum(n) = 2 + trsum(n-1) = 2 + 2 + trsum(n-2) = 2*2 + trsum(n-2) = 2n + trsum(0) = 2n + 2 C. –C. Yao
Matrix Addition Example line voidadd (matrix a, matrix b, matrix c, int m, int n) 1 { 2 for (int i = 0; i < m; i++) 3 for (int j = 0; j < n; j++) 4 c[i][j] = a[i][j] + b[i][j]; 5 } C. –C. Yao
Step Count of Matrix Addition Example voidadd (matrix a, matrix b, matrix c, int m, int n) { for (int i = 0; i < m; i++) { count++; // for for i for (int j = 0; j < n; j++) { count++; // for for j c[i][j] = a[i][j] + b[i][j]; count++; // for assigment } count++; // for last time of for j } count++; // for last time of for i } C. –C. Yao
Step Count of Matrix Addition Example (Simplified) line voidadd (matrix a, matrix b, matrix c, int m, int n) { for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) count += 2; count+2; } count++; } C. –C. Yao
Step Table of Matrix Addition Example C. –C. Yao
Fibonacci Numbers • 費式數列一開始的數為 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, … 每一個新的數都是前兩個數的和。如果把這數列的第一個數命名為 F0 並令 F0 = 0, F1 = 1, 則它的一般式為 Fn = Fn-1 + Fn-2 , n ≥ 2. C. –C. Yao
C++ Program of Fibonacci Numbers 1 voidfibonacci (int n) 2 // compute the Fibonacci number Fn 3 { 4 if (n <= 1) cout << n << endl; // F0 = 0, and F1 = 1 5 else { // compute Fn 6 int fn; int fnm2 = 0; int fnm1 = 1; 7 for (int i = 2; i <= n; i++) 8 { 9 fn = fnm1 + fnm2; 10 fnm2 = fnm1; 11 fnm1 = fn; 12 } // end of for 13 cout << fn << endl; 14 } // end of else 15 } // end of fibonacci C. –C. Yao
Step Count of Fibonacci Program • Two cases: • n = 0 or n = 1 • Line 4 regarded as two lines: 4(a) and 4(b), total step count in this case is 2 • n > 1 • Line 4(a), 6, and 13 are each executed once • Line 7 gets executed n times. • Lines 8 – 12 get executed n-1 times each. • Line 6 has s/e of 2 and the remaining lines have an s/e of 1. • Total steps for the case n > 1 is 4n + 1 C. –C. Yao
漸進符號 • 計算程式步驟數量幫助我們比較兩個程式的執行效率, 並且也提供預測當實際資料特性改變時執行時間成長的情形. • 決定一個程式所需要的精確步驟數是一個困難度極高的任務. 因為高階指令轉換成低階指令個關係以致計算高階指令的步驟數誤差較大. • 定義[Big“oh”]: f(n) = O(g(n)) 若且為若存在正的常數c與n0使得所有的 n,當 n ≥ n0時 f(n) ≤ cg(n). C. –C. Yao
Examples of Asymptotic Notation • 3n + 2 = O(n) 3n + 2 ≤ 4n for all n ≥ 3 • 100n + 6 = O(n) 100n + 6 ≤ 101n for all n ≥ 10 • 10n2 + 4n + 2 = O(n2) 10n2 + 4n + 2 ≤ 11n2 for all n ≥ 5 C. –C. Yao
Asymptotic Notation (Cont.) Theorem 1.2: If f(n) = amnm + … + a1n +a0, then f(n) = O(nm). Proof: for n ≥ 1 So, f(n) = O(nm) C. –C. Yao
Asymptotic Notation (Cont.) • 定義: [Omega] f(n) = Ω(g(n))若且為若存在正的常數c與n0使得所有的n,當 n ≥ n0時 f(n) ≥ cg(n). • Example: • 3n + 2 = Ω(n) • 100n + 6 = Ω(n) • 10n2 + 4n + 2 =Ω(n2) C. –C. Yao
Asymptotic Notation (Cont.) 定義: f(n) = Θ(g(n)) 若且為若存在正的常數c與n0使得所有的n,當 n ≥ n0時 c1g(n) ≤ f(n) ≤ c2g(n). C. –C. Yao
Asymptotic Notation (Cont.) Theorem 1.3: If f(n) = amnm + … + a1n +a0 and am > 0, then f(n) = Ω(nm). Theorem 1.4: If f(n) = amnm + … + a1n +a0 and am > 0, then f(n) = Θ(nm). C. –C. Yao
實際複雜度 • 假設程式 P 的複雜度為Θ(n) 而程式 Q 的複雜度為Θ(n2), 那麼我們可以斷言, 當 n 夠大時程式 P 一定跑得比 Q 快. • 考慮因素 “sufficiently large”. C. –C. Yao
Function Values C. –C. Yao