Transcript ch01資料結構導論
第一章-資料結構導論
1.1認識資料與資訊
1.2解析演算法
1.3程式與程式設計
1.4演算法
1.5演算法分析
written by Wei-ShenLai
1
1-1認識資料與資訊
資料結構(Data Structure)是一門和電腦硬體與軟體都有相關涉獵
的學科。
何謂資料(Data):
其中包含了演算法(Algorithm)、資料儲存架構、排序、搜尋、程
式設計概念與雜湊函數。
一種未經處理的原始文字(Word)、數字(Number)、符號
(Symbol)或圖形(Graph)等。
何謂資訊(Information):
當資料經過處理(Process)『以特定的方式有系統的整理、歸納甚至
進行分析後,就成為資訊』
資料結構可以看成是一種在資料處理過程中,一種分析、組織資料
的方法(Algorithm)與邏輯(Logic)。並考慮到了資料間的特性
與相互關係(Relationship)。
written by Wei-ShenLai
2
1-2解析演算法(Algorithm)
資料結構與演算法相輔相成:
何謂演算法:
程式是否有效率的完成預定任務,取決於 → 資料結構。
程式是否能清楚而正確的把問題解決,取決於→演算法。
根據韋氏字典中的定義:『在有限步驟內解決數學問題的程序』
在計算機領域中的定義:『為了解決某一個工作或問題,所需要有限
數目的機械性或重複性指令與計算步驟』
演算法必須符合下列五個條件:
輸入(Input):
輸出(Output):
每個指令或步驟必須是簡潔明確而不含糊的。
有限性(Finiteness):
至少會有一個輸出結果,不可以沒有輸出結果。
明確性(Definiteness):
0或多個輸入資料,這些資料必須有清楚的描述或定義。
在有限的步驟後一定會結束,不會產生無窮迴圈。
有效性(Effectiveness):
步驟清楚而且可行,能讓使用者用紙筆計算而求出答案。
written by Wei-ShenLai
3
演算法的表示方式:
一般文字:中英文。
虛擬語言(Pseudo-Language):SPARKS、PASCAL-LIKE等等。
表格或圖形。
流程圖:資料流程圖(DFD:Data Flow Diagram)及控制流程圖
(CFD:Control Flow Diagram)
程序語言:C、C++、Java、Visual Basic等等。
演算法與程式的不同?
程式不一定滿足有線性的要求,如作業系統或機器上的運作程式,除
非當機,否則永遠在等待迴路或記錄機器運作狀態。
written by Wei-ShenLai
4
SPARKS語言
虛擬語言(Pseudo-Language):一種不能直接放進電腦中執行的
語言,通常用來描述演算法。
語言結構:
指定指令(Assignment statement)
語法:變數←表示式或數值。
例如:
A←5(A變數設定為數值5)
A ←B+C(A變數設定為B變數所儲存的數值加上C變數所儲存的數值)
運算子(Operators):
布林運算子(Boolean operator):true(真)、false(偽)
邏輯運算子(Logical operator):and(且)、or(或)、not(非)
相關運算子(Relational operator):<(小於)、≦(小於等於)、>
(大於)、≧(大於等於)、=(等於)、≠(不等於)
數學運算子(Arithmetic operator):+(加)、-(減)、*(乘)、
**(次方)、/(除取商)、%(除取餘)
written by Wei-ShenLai
5
SPARKS語言
迴圈指令:
loop指令語法:
loop
forerver
for指令語法:
for 變數←起使值 to 結束值 by 遞增值 do
.....
next
while指令語法:
while 執行條件式 do
.....
.....
end
repeat指令語法:
repeat
written by Wei-ShenLai
.....
until 結束條件式
6
SPARKS語言
條件判斷指令:
if指令語法:
if 條件式 then
else
[條件不成立執行的區塊]
case指令語法:多重條件判斷式
case
[條件成立執行的區塊]
:條件式一:條件式一成立執行的區塊
:條件式二:條件式二成立執行的區塊
:條件式三:條件式三成立執行的區塊
.....
:else :其他情況執行的區塊
end
離開指令:
exit:跳出迴圈
return:返回呼叫程式
return(A):返回呼叫程式並傳回A的數值。
written by Wei-ShenLai
7
SPARKS語言
程式結構:
Procedure
.....
end
程序呼叫:
名稱(傳遞到程式的參數)
Call
程式名稱(傳遞到該程式的參數)
註解:
//註解
written by Wei-ShenLai
8
SPARKS語言寫作範例
問題:計算1+2+3+…+n傳回結果
Procedure Sum(n)
sum←0
for i ←1 to n do
sum←sum+I
next
return sum
end Sum
....
sum← Call Sum(5)
written by Wei-ShenLai
9
1-3程式(Program)與程式設計(Programming)
系統生命週期法
需求認識(Requirement):瞭解程式所需解決的問題是什麼,有
哪些輸入與輸出等。
設計規劃(Design and Plan): 根據需求,選擇合適的資料結構,
並以任何的表示方式來寫一個演算法以解決問題。
分析討論(Analysis and Discussion): 思考其他可能的演算法及
資料結構,最後再選出最適當的標的。
編寫程式(Coding):把分析的結論,寫成初步的程式碼。
測試檢驗(Verification):最後必須確認程式的輸出是否符合需求,
這個步驟得細部的執行程式並進行許多的相關測試。
written by Wei-ShenLai
10
1-3-1 結構化程式設計
由下而上法(Bottom Up Approach):
指程式設計師將整個程式需求最容易的部分先編寫,在逐步擴大來完
成整個程式。
由上而下法(Top-Down Approach)
將整個程式需求從上而下、由大到小逐步分解成較小的單元或模組
(Module),再針對各個模組分別開發,不但減輕設計者負擔、可
讀性較高,對於日後維護也容易許多。
結構化
written by Wei-ShenLai
11
1-3-1 結構化程式設計
資料型態(Data Type):
基本資料型態(Atomic data type):
結構型資料型態(Structure data type):
整數、浮點數、字元等等。
一個資料實體包含其他資料型態,如字串(string,由字元組成)、集
合(set)、陣列(array)
抽象資料型態(Abstract data type,ADT):
定義一些結構型資料型態以及操作該資料型態的動作。如堆碟(Stack)、
佇列(Queue)等等。
written by Wei-ShenLai
12
1-4
遞迴程式(Recursion)
利用遞迴觀念簡化程式與演算法設
計。
範例:以C語言為例(P1-15)
問題計算N!=N*(N-1)*….*2*1
#include <stdio.h>
void main(){
int i,j,sum=1;
for(i=0;i<=4;i++){
for(j=i;j>0;j--)
}
}
sum*=j;
printf("%d!=%3d\n",i,sum);
sum=1;
引入標準標頭檔。
標頭檔(Header File):定義常
數與函數的使用方式,必須書寫
於程式最上方。
main()為C語言規定的程式進入點。
void代表不傳回任何資料。
int代表整數資料型態。
每一敘述必須以『;』結尾。
左列程式宣告整數變數i、j、
sum。
C語言規定宣告變數必須於函數
最前端部位,且程式中欲使用的
變數都必須明確宣告。
written by Wei-ShenLai
13
1-4
遞迴程式(Recursion)
利用遞迴觀念簡化程式與演算法設計。
範例:以C語言為例(P1-15)
問題計算N!=N*(N-1)*….*2*1
#include <stdio.h>
程式內自行定義的函數,必須於
int
recursive(int);
void main(){
main()上方定義。
int i;
for(i=0;i<5;i++)
}
int
recursive(int i){
int sum;
if(i==0)
遞迴想法:
N! = N* (N-1)!
return(1);
else
printf(“%d階層值為%3d\n",i, recursive(i) );
sum=i*recursive(i-1);
return sum;
}
written by Wei-ShenLai
14
1-4-1 河內塔問題(Tower of Hanoi)
問題:如何將n個碟子由小至大(由上至下)由1號木樁搬到3號木
樁,搬動過程必須遵守越上面的碟子越小的規則。
written by Wei-ShenLai
15
1-4-1 河內塔問題(Tower of Hanoi)
written by Wei-ShenLai
16
1-4-1 河內塔問題(Tower of Hanoi)
written by Wei-ShenLai
17
1-4-1 河內塔問題(Tower of Hanoi)
written by Wei-ShenLai
18
1-4-1 河內塔問題(Tower of Hanoi)
an=2an-1+1
=2*(2an-2+1)=4an-2+2+1
=4*(2an-3+1)+2+1=8*an-3+4+2+1
…….
=2n-1a
N 2
1+
2
K 0
=2n-1+2n-1-1
=2n-1
written by Wei-ShenLai
K
N 2
( 2 K 2 N 1 1
)
K 0
19
1-4-1 河內塔問題(Tower of Hanoi)
演算法:
Procedure Hanoi(n,p1,p2,p3)
if(n=1) then
else[
輸出盤子從木樁p1搬到木樁p3;
Hanoi(n-1,p1,p3,p2);
輸出盤子n-1從木樁p1搬到木樁p3;
Hanoi(n-1,p2,p1,p3);
]
end Hanoi
written by Wei-ShenLai
20
1-4 遞迴程式
直接遞迴(Direct Recursion):
遞迴程式內容中,允許直接呼叫該程式本身。
間接遞迴(Indirect Recursion):
遞迴程式內容中,如果呼叫其他遞迴程式,再從其他遞迴程式呼叫原
來的遞迴程式。
直接遞迴
functionA(){
…..
functionA()
….
}
間接遞迴
functionA(){
…..
functionB()
….
}
functionB(){
…..
functionA()
….
}
遞迴程式的優缺點:
優點:程式簡短、可讀性高。
缺點:程式呼叫必須使用暫存堆疊與活動紀錄表來保留程式的執行狀
態,所以執行時間較長。
written by Wei-ShenLai
21
範例1.4.1 最大公因數GCD(Greatest Common Divisor)
GCD(n, m mod n), n 0
GCD(m, n)
m
,
n
0
int gcd(int m,int n)
{
if(n==0)
return(m);
else
return(gcd(n,m%n));
}
written by Wei-ShenLai
22
範例1.4.2 費勃那函數Fibonacci
Fn 1 Fn 2 , n 1
Fn 1, n 1
0, n 0
written by Wei-ShenLai
int fib(int n)
{
if(n==0)
return(0);
if(n==1)
return(1);
else
return(fib(n-1)+fib(n-2));
}
23
練習:遞迴問題
問題一:
n!
C
m!(n m)!
n
m
Cmn Cmn 1 Cmn 11
問題三:
n 1, m 0
Ack(m, n) Ack(m 1,1), n 0
Ack(m 1, Ack(m, n 1))
C0n Cnn 1
問題二:
n 1
X
*
X
Xn
X , n 1
written by Wei-ShenLai
問題四:
F ( a, n) 1 a a 2 a n
F (a, n 1) * a 1
F ( a, n)
a , n 1
24
1-5 演算法的效能分析
T (n) 3n 3 2n 2 5n
找到常數c 10與n0 0,當n n 0時,
3n 3 2n 2 5n 10n3
則時間複雜度為O n 3
2
i
O
n
1i n
n(n 1) n 2 n
i 1 2 3 n
2
2
1i n
找到常數c 1與n0 0,當n n 0時,
n2 n
n2
2
則時間複雜度為O n 2
written by Wei-ShenLai
25
1-5 演算法的效能分析
(1)
..............
X←X+1
...............
O(1)
(2)
for i←1 to n do
..............
X←X+1
...............
next
O(n)
(3)
for i←1 to n do
for j←1 to n do
..............
X←X+1
...............
next
next
O(n2)
written by Wei-ShenLai
26
Big “oh”:上限(upper bound)
定義:[ Big “ oh ” ] 若且唯若f(n)=O(g(n))(讀作“ f of n is big oh of g of n”)則存在大於0的常數
值c和n0,使的對所有的n值,n≧ n0 時,f(n)≦cg(n)均成立。
範例1.15:
證明:3n+2=O(n)
n 2
3n 2 4n
證明:10n2+4n+2=O(n2)
n 5
10n 2 4n 2 11n 2
證明:6*2n+n2=O(2n)
n 4
6 * 2n n 2 7 * 2n
O(1):常數
O(n):線性函數
O(n2):二次函數
O(n3):三次函數
O(2n):指數函數
written by Wei-ShenLai
27
Omega:下限(lower bound)
定義:[ Omega ] 若且唯若 f (n) g n (讀作“ f of n is omega of g of n”)則存在大於0的常數值c和
n0,使的對所有的n值,n≧ n0 時,f(n)≧cg(n)均成立。
範例1.16:
證明:3n 2 n
n 1
3n 2 3n
證明:10n
2
4n 2 n2
n 1
10n 2 4n 2 n 2
n
2
n
證明:6 * 2 n 2
n 1
6 * 2n n 2 2n
written by Wei-ShenLai
28
Theta:(漸近表示法)
定義:[ Theta ] 若且唯若 f (n) g n (讀作“ f of n is theta of g of n”)則存在大於0的常數值c1、 c2
和n0,使的對所有的n值,n≧ n0 時, c1g(n)≦f(n)≦c2g(n)均成立。
定理1.2
:若f n a mn m ... a1n a 0且a m 0,則f n n m
定理1.3
:若f n a mn m ... a1n a 0且a m 0,則f n n m
定理1.4
:若f n a mn ... a1n a 0且a m 0,則f n n
m
written by Wei-ShenLai
m
29
1-5 演算法的效能分析(計算)
written by Wei-ShenLai
30
補充:魔術矩陣(Magic square)
問題:我們選擇以一個數學模式建立的問題當作複雜度分析的最後一個問題,即
建立一個魔術方陣。魔術方陣是一n*n的矩陣,其中填入1到n*n之間的整數,
使的各行,各列,以及兩個主對角線上的元素和均相等。在此列中加總同為65。
注意:n必須為奇數。
想法:每次往左上方找空位,如果沒有空位則往下找。這樣會造成行列總和會相
等(65)。
25 25* (25 1)
i
2
i 1
25*13 65
5
5
5
某對角線總和為65
5 * j j 4
i
5 * j 2
2
i j
總和為65
15 8
16 14 7
j 4
j 11
由11的位置往回逆推1的起始位置。
總和為65
5 23
22 20 13 6
4
3 21 19 12 10
9
written by Wei-ShenLai
1 24 17
2 25 18 11
總和為65
31
範例1.21[Magic square]:
n2
i=0;
j=(size-1)/2;
for ( count=2; count<=size*size; count++ ) {
row=(i-1<0)?(size-1): i-1;
column=(j-1<0)?(size-1):(j-1);
if (square[ row ][ column ])
i=(++i)%size;
else {
i=row;
j =(j-1<0)?(size-1):(--j);
}
square [ i ][ j ]=count;
}
複雜度為:
n
written by Wei-ShenLai
2
32
1-5 演算法的效能分析
線性問題:
O(1):常數
O(log2n):次線性函數
O(n):線性函數
非線性問題:
O(n2):二次函數
O(n3):三次函數
O(2n):指數函數
1<log(n)<n<n*log(n)<n2<n3<2n<n!
written by Wei-ShenLai
33