以下我們正式定義大O記號:
[定義] Big-O: (O 代表order之意)
令f(n)與g(n)是由非負整數對應至實數的函數,若存在正實數常數c>0和正整數常數n0使得對所有的nn0而言,f(n)cg(n)成立,則我們說f(n)=O(g(n))。(唸作 「f(n)是屬於Big-O of g(n)」,比較正式的英文唸法為「f of n is of Big-O of g of n」)。
我們根據上列定理設計出一個屬於平方根量級的演算法 演算法Prime2:
Algorithm Prime2(n):
Input:一個大於2的正整數n
Output:true或false(表示n是質數或不是質數)
for i=2 to do
if (n%i)=0 return false
return true
範例程式(檔名:Prime1AP.java)
1: //檔名:Prime1Ap.java
2: //說明:此程式可輸入一個大於2的整數,並判斷此整數是否為質數(prime number)
3: import javax.swing.JOptionPane;
4: public class Prime1Ap {
5: public static void main(String[] 參數){
6: int 整數n;
7: String 輸入字串,顯示字串;
8: 輸入字串=JOptionPane.showInputDialog("請輸入大於2的整數n?");
9: 整數n=Integer.parseInt(輸入字串);
10: boolean 是質數;
11: long 演算法執行前時間=System.currentTimeMillis();
12: 是質數=Prime1(整數n);
13: long 演算法執行後時間=System.currentTimeMillis();
14: long 演算法執行時間=演算法執行後時間-演算法執行前時間;
15: if(是質數) 顯示字串=整數n+"是質數";
16: else 顯示字串=整數n+"不是質數";
17: 顯示字串+=("\n演算法執行時間為"+演算法執行時間+"毫秒(milli-seconds)");
18: JOptionPane.showMessageDialog(null,顯示字串);
19: System.exit(0);
20: } //方法:main() 定義區塊結束
21: static boolean Prime1(int n) {
22: for (int i=2;i<=n-1;++i)
23: if (n%i==0) return false;
24: return true;
25: }
26: } //類別:Prime1Ap 定義區塊結束
執行結果(命令視窗指令:java Prime1AP)
範例程式1-2.質數檢查演算法1執行程式。
範例程式(檔名:Prime2AP.java)
1: //檔名:Prime2Ap.java
2: //說明:此程式可輸入一個大於2的整數,並判斷此整數是否為質數(prime number)
3: import javax.swing.JOptionPane;
4: public class Prime2Ap {
5: public static void main(String[] 參數){
6: int 整數n;
7: String 輸入字串,顯示字串;
8: 輸入字串=JOptionPane.showInputDialog("請輸入大於2的整數n?");
9: 整數n=Integer.parseInt(輸入字串);
10: boolean 是質數;
11: long 演算法執行前時間=System.currentTimeMillis();
12: 是質數=Prime2(整數n);
13: long 演算法執行後時間=System.currentTimeMillis();
14: long 演算法執行時間=演算法執行後時間-演算法執行前時間;
15: if(是質數) 顯示字串=整數n+"是質數";
16: else 顯示字串=整數n+"不是質數";
17: 顯示字串+=("\n演算法執行時間為"+演算法執行時間+"毫秒(milli-seconds)");
18: JOptionPane.showMessageDialog(null,顯示字串);
19: System.exit(0);
20: } //方法:main() 定義區塊結束
21: static boolean Prime2(int n) {
22: for (int i=2;i<=Math.sqrt(n);++i)
23: if (n%i==0) return false;
24: return true;
25: }
26: } //類別:Prime2Ap 定義區塊結束
執行結果(命令視窗指令:java Prime2AP)
範例程式1-3.質數檢查演算法2執行程式。
習題
一、 資料結構的定義為何?演算法的定義為何?為何資料結構語演算法經常一併被提及?
二、 設計一個時間複雜度為O( )的演算法,求一個正整數n有多少個因數。以虛擬碼表示你的演算法,並說明為何其時間複雜度為O( )?
三、 設計一個最差時間複雜度為O( )的演算法,求一個正整數n不等於本身的最大因數。以虛擬碼表示你的演算法,並說明為何其最差時間複雜度為O( )?
四、 設計一個演算法,求一個正整數n不等於本身的最大因數。以虛擬碼表示你的演算法,並求其最差時間複雜度與最佳時間複雜度?(最佳時間複雜度可以為O(1)而最差時間複雜度可以為O( ))
五、 設計一個演算法,求一個正整數n所有因數的總合。以虛擬碼表示你的演算法,並求其時間複雜度?
六、 設計一個演算法,求一個正整數n是否為完美數(perfect number)。以虛擬碼表示你的演算法,並求其時間複雜度?
註:一個整數被稱為完美數(perfect number)若它等於除了它自身之外所有因數的和。例如,1+2+3=6,因此6為perfect number;而1+2+48,因此8不是perfect number。
七、 設計一個演算法,求小於正整數n的所有完美數(perfect number)。以虛擬碼表示你的演算法,並求其時間複雜度?
註:一個整數被稱為完美數(perfect number)若它等於除了它自身之外所有因數的和。例如,1+2+3=6,因此6為perfect number;而1+2+48,因此8不是perfect number。
八、 設計一個演算法,求一個正整數m與一個正整數n是否互質。以虛擬碼表示你的演算法,並將之轉換為Java語言程式碼?
九、 以大O記號寫出下列函數?
(1) (2)
十、 試決定下列片斷程式中的指令x←x+1的執行次數? (87年資料處理高考)
(1)for i←1 to n do
for j←1 to n do
x←x+1
end
end
(2)for i←1 to n do
for j←i to n do
for k←j to n do
x←x+1
end
end
end
(3)for i←1 to n do
j←i
for k←j+1 to n do
x←x+1
end
end
(4)k←100000
while k5 do
k←k div 10
x←x+1
end
十一、 若一個程式執行的時間是1000n2+n log n2,則相當於:(A).O(n2) (B).O(n log n) (C).O(n3) (D). O(n2n log n2)。 (88年普考)
十二、 證明 =O(n2)。 作者: mm117777 時間: 2012-7-8 21:50:01
資料結構
例如,以後進先出(Last In First Out, LIFO)的方式儲存與擷取的資料集合構成一個稱為堆疊(stack)的資料結構;以先進先出(First In First Out, FIFO) 的方式儲存與擷取的資料集合構成一個稱為佇列(queue)的資料結構等等。
選擇適當的資料結構可以幫助我們解決特定的問題,例如,若我們選擇堆疊以後進先出的方式儲存與擷取文書編輯器的編輯動作(action),則每次我們執行[取消(undo)]功能時,一定都是取消最後一個我們執行過的編輯動作(如圖1-1所示)。因此,只要我們有足夠的空間儲存堆疊的資料,理論上我們可以復原任何一個我們執行過的編輯動作。
次序 1 2 3 4 5 6
動作 輸入A 輸入B 輸入C 復原(UnDo) 復原(UnDo) 輸入Z
文件內容 A AB ABC AB A AZ
堆疊
輸入A
輸入B
輸入A
輸入C
輸入B
輸入A
輸入C
輸入B
輸入A
輸入B
輸入A
輸入Z
輸入A
圖1-1. 文書編輯器以堆疊(stack)後進先出(Last In First Out, LIFO)的方式儲存與擷取編輯動作
作者: mm117777 時間: 2012-7-8 21:50:11
資料結構
例如,以後進先出(Last In First Out, LIFO)的方式儲存與擷取的資料集合構成一個稱為堆疊(stack)的資料結構;以先進先出(First In First Out, FIFO) 的方式儲存與擷取的資料集合構成一個稱為佇列(queue)的資料結構等等。
選擇適當的資料結構可以幫助我們解決特定的問題,例如,若我們選擇堆疊以後進先出的方式儲存與擷取文書編輯器的編輯動作(action),則每次我們執行[取消(undo)]功能時,一定都是取消最後一個我們執行過的編輯動作(如圖1-1所示)。因此,只要我們有足夠的空間儲存堆疊的資料,理論上我們可以復原任何一個我們執行過的編輯動作。
次序 1 2 3 4 5 6
動作 輸入A 輸入B 輸入C 復原(UnDo) 復原(UnDo) 輸入Z
文件內容 A AB ABC AB A AZ
堆疊
輸入A
輸入B
輸入A
輸入C
輸入B
輸入A
輸入C
輸入B
輸入A
輸入B
輸入A
輸入Z
輸入A
圖1-1. 文書編輯器以堆疊(stack)後進先出(Last In First Out, LIFO)的方式儲存與擷取編輯動作