Presentation is loading. Please wait.

Presentation is loading. Please wait.

陣列的抽象定義是一組具有相同資料 型態 (data type) 的元素,所組成 的有序集合 (ordered set) ,通常 儲存在一塊連續的記憶體上 。 陣列的應用技巧可開啟善用陣列資料 結構之門。 陣列在實體記憶空間中配置的關係可 引領各位瞭解陣列資料結構如何存放 在電腦中,以及程式語言、編譯器如.

Similar presentations


Presentation on theme: "陣列的抽象定義是一組具有相同資料 型態 (data type) 的元素,所組成 的有序集合 (ordered set) ,通常 儲存在一塊連續的記憶體上 。 陣列的應用技巧可開啟善用陣列資料 結構之門。 陣列在實體記憶空間中配置的關係可 引領各位瞭解陣列資料結構如何存放 在電腦中,以及程式語言、編譯器如."— Presentation transcript:

1

2 陣列的抽象定義是一組具有相同資料 型態 (data type) 的元素,所組成 的有序集合 (ordered set) ,通常 儲存在一塊連續的記憶體上 。 陣列的應用技巧可開啟善用陣列資料 結構之門。 陣列在實體記憶空間中配置的關係可 引領各位瞭解陣列資料結構如何存放 在電腦中,以及程式語言、編譯器如 何運作,方使陣列得以有效率地為吾 人所用。

3 線性 ( 有序 ) 串列 串列形式 (e 0, e 1, e 2, …, e n-1 ) 其中 e i 為串列元素 n >= 0 是一個有限整數 串列大小為 n

4 線性串列 L = (e 0, e 1, e 2, …, e n-1 ) 關係 e 0 是第零個元素 e n-1 是最後一個元素 e i 緊接著 e i+1

5 線性串列例子 班上學生 = (Jack, Jill, Abe, Henry, Mary, …, Judy) 資料結構之考試 = ( 考試一, 考試二, 考試三 ) 一週之七日 = (S, M, T, W, Th, F, Sa) 月份 = (Jan, Feb, Mar, Apr, …, Nov, Dec)

6 任何資料結構的引用,皆需透過 程式語言先行宣告,陣列的宣告 必須包含三項要素: 陣列的宣告與使用  (1) 陣列的名稱;  (2) 陣列的大小;  (3) 陣列中元素的資料型態。

7 陣列內元素值的指定 assignment 1 main() 2 { int list[5]; 3 int i; 4 for (i=0 ; i<5 ; i++) list[i]=i+1; 5 } 陣列 list 的邏輯圖示 list[0]1 list[1]2 list[2]3 list[3]4 list[4]5 //list 為一整數陣列,共有 5 個元素。

8 0123456 線性串列之陣列表示法 使用一個一維陣列 element[ ] abcde L = (a, b, c, d, e) 大小為 5

9 一維陣列 list[]={10,21,55,…,88,45,120} 實際上在電 腦記憶裡的儲存情形

10 一維陣列 若一維陣列 A 在記憶體中的起點為,而且任一 元素佔用 l 位元組,若有 n 個元素,則陣列 A 在 記憶體中的配置位置,可描繪如圖 2-7 。其中 A[i] 在記憶體中的位址為 +i  l : A[i] 在記憶體中的位址為 +i  l 陣列的存取時間與元素存放的位置無關,亦即編譯器 可在相同的時間內,決定任何位置陣列元素的位址, 其存入(或取出)的時間皆為一樣。

11 一維陣列 陣列 A 是一個有 n 個元素的一維陣列,其 元素分別為 A[0] 、 A[1] 、 … 、 A[n-1] 。若 其起始位址為 α ,而且各陣列元素大小為 d ,那麼 A[i] 的位址為 α+(i-1)*d 。

12 宣告 int list[5]; list[0] list[1] list[2] list[3] list[4] 19 21 5 115 28 如果每個元素大小為 len 個 bytes list[1] 的位址是 X + 1 × len list[0] 的位址是 X list[2] 的位址是 X + 2 × len list[k] 的位址是 X + k × len : 陣列的元素在記憶體中是連續的位置。 List[0] 是陣列 list 的頭一 個元素。 List[1] 是編號 1 號元素,它緊接著 0 號元素。同樣的, list[i+1] 的位置是緊接著 list[i] 的 陣列及定義

13 有一整數陣列 int A[60]; 則此陣列共佔多少位元 組(設 sizeof(int)=2 )?若 A[0] 在記憶體中的位 址為 03C4 16 ,則元素 A[20] 的位址為何? A 陣列共佔 60 ×2 = 120 (bytes) A[20] 的位址 = A[0] 的位址 + 位移量 = 03C4 16 + (20 – 0 ) × 2 = 03C4 16 + 28 16 = 03EC 16 list[0] list[1] list[2] list[20] list[59] ﹋ ﹋ ﹋ ﹋ ﹋ ﹋﹋ ﹋ 位移量位移量

14 二維陣列 當二維陣列空間轉為一維記憶體空間時,可 採以列為優先 (row major) 或採以行為優 先 (column major) 的配置方式。 以列為優先的次序,指的是先依列由小到大 的順序,再依行由小到大的順序存放資料, 即第 0 列所有資料依行序存妥後,再將第 1 列 所有資料依行序存妥 … ,依此類推。 行為優先的次序,則先依行由小到大的順序, 再依列由小到大的順序存放陣列的資料。 現今大多的程式語言皆依以列為優先的原則設計。

15 二維陣列 ─int A[N][M]

16 二維陣列的實際記憶體配置

17 0 0 1 2 3 4 5 1234 6 ×5 19 25 二維陣列在邏輯上表示為平面 第 1 列第 2 行: List[1][2] 值是 19 第 3 列第 1 行: List[3][1] 值是 25 實體排列順序是線性的 以列為主 (row major) 以行為主 (column major) (0,0) ﹋ ﹋ ﹋ ﹋ (0,1) (0,2) (0,3) (0,4) (1,0) (1,1) (5,4) (5,3) (0,0) ﹋ ﹋ ﹋ ﹋ (1,0) (2,0) (3,0) (4,0) (5,0) (0,1) (5,4) (4,4) (1,1)

18 二維陣列 以列優先 二維陣列在記憶體裡以列優先的排列

19 二維陣列 以列優先 二維陣列在記憶體裡以列優先的排列 A 35 之前共有 26 個陣列元素 假設第一個元素所在的 位置為 7300H 則 Loc(A 35 )=7300H+3*7 +5-1 = 7300H+25 =7300H+19H=7319H 。

20 二維陣列 以列優先 二維陣列在記憶體裡以列優先的排列 假定有 n 列、 m 行且每個陣列元素佔 d 個位 元組,陣列的起啟位置為 α ,則 A(i,j) 在記 憶體裡的位置為:

21 二維陣列 以行優先 以行優先 A 35 之前有 28 個陣列元 素,所以 Loc(A 35 )= 7300H+28 =7300H +1CH=731CH

22 二維陣列 推導 A(i,j) 的位置公式得到:

23 如果每個元素大小為 len 個 bytes ,而且 list[0][0] 的位址為 X ,則: list[0][3] 的位址是 X + (3 – 0) ×len = X + 3 × len list[4][3] 的位址是 X + ((4 - 0)×5 +(3 - 0)) × len = X + (4 ×5 +3) × len list[4][3] 之前有 4 整列(每列有 5 個元素)加 3 個元素 list[m][n] 的位址是 X + ((m - 0)×5 +(n - 0)) × len = X + (m×5 +n) × len list[m][n] 之前有 m 整列(每列有 5 個元素)加 n 個元素 將其整理為通式,若有陣列 list[r][c] : list[0][0] 的位址是 X list[m][n] 的位址是 X + ((m - 0) ×c +(n - 0)) × len = X + (m × c + n) × len r c × + m n m × c + n

24 三維陣列與高維陣列 在電腦的內部運作中,編譯器可先行找出 陣列宣告的上下限值: u 1, u 2, …, u n , 然後利用 n-2 個乘法,求出上式的 w 1, w 2, …, w n-1 (w n =1 ,不必求之 ) ,先 行存下。而計算 A[i 1 ][i 2 ]…[i n ] 的位址 時,即可利用上式,以 n 個乘法和 n+1 個 加法求得其位址值。 也因而陣列是一個隨機 (random access) 存取的結構,其元素的存取與 存放的位置無關。

25 三維陣列中元素的定址關係

26 三維陣列 A[C1][C2][C3] ,我們可以想像三維陣列是由小方塊疊成的立方體: C1 C2 C3 共有 C1 層 每層共有 C2 ×C3 個 A[a][b][c] 的位址計算:在它之上有整整 a 層,同一層中在它之前有整整 b 列, 而同列中在它之前有 c 個元素。因此 A[a][b][c] 拉成線性相當於距離 A[0][0][0] 有 ( a × C2 × C3 + b × C3 + c ) 個元素 C1 C2 C3 a b c ((a ×C2) + b) ×C3) + c = a × C2× C3 + b × C3 + c × × + +

27 以下是陣列的五種基本的運算 (operation) : 1. 檢索(讀出)編號為 i 的元素內含值 intvalue = list[4] ; 2. 將新值寫入編號為 i 的元素位置 list[4] = NewValue ; 3. 在編號 i 的位置插入一新元素,原來 i 和之後的元素各往後挪一個位置。 如果陣列編號從 0 到 n-1 ,則 n-1 號元素可能將喪失 4. 刪除編號 i 的元素,原來 i +1 和之後的元素各往前挪一個位置。第 n-1 號元素變成無意義(或填入固定值) 5. 將一陣列的所有元素複製到另一陣列(陣列的複製)

28 List(0) 5 List(1) List(7) List(6) List(5) List(4) List(3) List(2) 25 11 26 39 18 120 50 插入 67 至 list[3] 5 25 11 67 26 39 18 120

29 加入一個元素 abcde size = 5 agbcde size = 6 add(1,g)

30 加入一個元素 假設要把 100 插入到 list 的第二個位子 必須先將 list[23] 的 120 搬到 list[24] 把 45 搬到 list[23] ,把 88 搬到 list[22] 依此類推把原來 list[2] 到 list[23] 的內容都 搬到 list[3] 到 list[24] 去 最後再把 100 存到 list[2] 。

31 加入一個元素

32 List(0) 5 List(1) List(7) List(6) List(5) List(4) List(3) List(2) 25 11 26 39 18 120 50 刪除 list[3] 5 25 11 39 18 120 50 0

33 刪除一個元素 假如我們欲刪除的是 list[2] 的 100 必須把 list[3] 的值複製到 list[2] list[4] 的值複製到 list[3] 依此方法將 list[2]~list[24] 搬移到 list[3]~list[23]

34 刪除一個元素 ─ 虛擬碼 procedure delete( i) { index j; for (j  i+1 to 陣列結尾 ) list( j-1)  list(j); }

35 複製陣列 ─ 虛擬碼 /* a 是原始陣列, b 是欲放複製內容的陣列 */ procedure copy ( a,b) { index i; for( i  0 to 陣列結尾 ) b(i)  a(i) }

36 陣列的字串應用 char data[20]=”data structure”;

37 字元大小寫的轉換 ─ 虛擬碼 procedure toupper (ch) { if (ch 屬於 ’a’ 到 ’z’) 傳回 (ch+32); else 傳回 (ch); }

38 計算字串長度 ─ 虛擬碼 /* str 是一字串 */ procedure strlenr (str) { for(str 開始 to str 結尾 ) num  num+1; }

39 字串複製 ─ 虛擬碼 /* source[] 是原始字串, dest[] 是複製字串 */ procedure strcopy (dest[],source[]) { for(source 開始 to source 結尾 ) dest(i)  source(i); dest(i+1)  Null ; }

40 二字串串聯 ─ 虛擬碼 procedure cat (str1[],str2[],dest[]) { 把字串 str1 複製到字串 dest; 記錄 str1 的長度 i ; 從索引 i+1 開始,複製字串 str2 到 dest 中 ; }

41 字串比較 ─ 虛擬碼 procedure strcmp (str1[],str2[]) { index i; if ( 兩字串中的所有元素都滿足 str1(i)== str2(i)) (return 0) else{ if ( 第一個不相等元素滿足 str1(i)>str2(i)) 傳回 +1; else{ 傳回 –1;} } }

42 字串搜查 假設我們要在第一個字串中尋找第二個 字串的內容 首先我們先在第一個字串中找尋與第二 個字串的第一個字元相同的位置 然後連續比較兩個字串的其他字元,直 到第二個字串的 NULL 出現為止 傳回第一個字串中與第二個字串的第一 個字元相同的位置。

43 字串搜查 如果 NULL 字元在第一個字串中先被找到, 那麼表示第二個字串不存在第一個字串 中,便傳回 -1 如果在連續地比較兩個字串的字元時, 發現任何一個字元不符合,那麼就要重 新在第一個字串中搜尋第二個字串的第 一個字元。

44 字串搜查 Step1 : i=0; Step2 : 如果 str1[i]=NULL ,則停止 ( 沒找到,第一個字 串為空字串 ) 。 Step3 : 如果 str1[i]≠str2[i] ,則跳到 Step8 。 Step4 : j=1 Step5 : 如果 str2[j]=NULL ,則停止(第二個字串結束或 為空字串)。 Step6 : 如果 str1[j+i]=NULL (沒有找到)。 Step7 : 如果 str1[j]=str2[j+i] ,則 j=j+1 ;跳到 Step5 。 Step8 : i=i+1 ;跳到 Step2 。

45 求第 n 項的費氏級數 1, 1, 2, 3, 5, 8, 13, 21, 34, …

46 求第 n 項的費氏級數 Fib[0]=1; Fib[1]=1; printf("\nPlease enter the ith element "); scanf("%d",&n); // 輸入要求第幾項的級數 i=2; printf("The value of the %dth element is: ",n); while (i<=n-1) { Fib[i]=Fib[i-1]+Fib[i-2]; // 前二項之和 i++; } printf("%d\n",Fib[n-1]);}

47 二維陣列的應用 二維陣列可以用來儲存數學的矩陣及行列式,因此可以用來解決諸 如 “ 解連立方程組 ” 等線性代數問題 a 00 a 01 a 02 a 03 a 10 a 11 a 12 a 13 a 20 a 21 a 22 a 23 3列3列 4行4行 3 ×4 資料結構示意圖 a 00 a 01 a 10 a 11 a 20 a 21 a 22 a 12 a 02 a 23 a 13 a 03 數學習慣表示法

48 a 00 a 01 . . a 0(n-1) a 10 a 11 . . a 1(n-1) . . . a (m-1)0 . . a (m-1)(n-1) m × n A=A= a 00 a 10 . . a (m-1)0 a 01 a 11 . . a (m-1)1 . . . a 0(n-1) . . a (n-1)(m-1) n × m B = A t = 1 4 2 5 3 6 9 8 7 12 11 10 A=A= 3 × 4 B = A t = 1 4 2 5 3 6 9 8 7 12 11 10 4 × 3

49 a 00 a 01 . . a 0(n-1) a 10 a 11 . . a 1(n-1) . . . a (m-1)0 . . a (m-1)(n-1) m × n 1 4 2 5 3 6 9 8 7 12 11 10 4 × 3 b 00 b 01 . . b 0(n-1) b 10 b 11 . . b 1(n-1) . . . b (m-1)0 . . b (m-1)(n-1) m × n + + 0 3 1 4 2 5 8 7 6 11 10 9 4 × 3 1 7 3 9 5 11 17 15 13 23 21 19 4 × 3 = = a 00 +b 00 a 01 + b 01 . . a 0(n-1) + b 0(n-1) a 10 +b 10 a 11 + b1 01 . . a 1(n-1) + b 1(n-1) . a (m-1)0 +b (m-1)0 a (m-1)1 + b (m-1)1 ‧‧ a (m-1)(n-1) +b (m-1)(n-1) m × n

50 c 00 = [a 00 a 01 ‧‧‧ a 0(n-1) ] × = a 00 × b 00 + a 01 × b 10 + ‧‧‧ + a 0(n-1) × b (n-1)0 (n 個乘法 ) n-1 = Σ a 0k ×b k0 k=0 A m×n × B n×t = C m×t b 00 b 10 ‧‧‧ b (n-1)0 n-1 c ij = Σ a ik ×b kj k=0 c 00 是 A 矩陣的第 0 列向量乘上 B 矩陣的第 0 行向量 c ij 是 A 矩陣的第 i 列向量乘上 B 矩陣的第 j 行向量

51 矩陣的運算 矩陣 ( 或行列式 ) 是一種數學上的重要 結構,恰可用二維陣列表示之。 若矩陣 A 是一個 3  4 的整數矩陣,我們可 以 C 語言宣告矩陣 A int A[3][4]; 此二維整數陣列 A 共有 3 列 4 行,而 A[i][j] 即對應了矩陣 A 之元素 a ij 。

52 矩陣轉置及相加 演算法 2-3 矩陣轉置 輸入: m  n 矩陣 A 輸出:矩陣 B , B=A T 1 將二維矩陣 A 的元素載入二維陣列 A 中: A[i][j]=a ij 2for (i=0; i { "@context": "http://schema.org", "@type": "ImageObject", "contentUrl": "http://images.slideplayer.com/16/4968364/slides/slide_52.jpg", "name": "矩陣轉置及相加 演算法 2-3 矩陣轉置 輸入: m  n 矩陣 A 輸出:矩陣 B , B=A T 1 將二維矩陣 A 的元素載入二維陣列 A 中: A[i][j]=a ij 2for (i=0; i

53 演算法 2-4 矩陣相加 輸入: m  n 矩陣 A 輸出:矩陣 C , C=A+B 1 將二維矩陣 A,B 的元素載入二維陣列 A,B 中: A[i][j]=a ij ; B[i][j]=b ij 2for (i=0; i { "@context": "http://schema.org", "@type": "ImageObject", "contentUrl": "http://images.slideplayer.com/16/4968364/slides/slide_53.jpg", "name": "演算法 2-4 矩陣相加 輸入: m  n 矩陣 A 輸出:矩陣 C , C=A+B 1 將二維矩陣 A,B 的元素載入二維陣列 A,B 中: A[i][j]=a ij ; B[i][j]=b ij 2for (i=0; i

54 演算法 2-5 矩陣相乘 輸入: m  n 矩陣 A , n  p 矩陣 B 輸出:矩陣 C , C=A  B 1 將二維矩陣 A,B 的元素載入二維陣列 A,B 中: A[i][j]=a ij ;B[i][j]=b ij ; 2for (i=0; i { "@context": "http://schema.org", "@type": "ImageObject", "contentUrl": "http://images.slideplayer.com/16/4968364/slides/slide_54.jpg", "name": "演算法 2-5 矩陣相乘 輸入: m  n 矩陣 A , n  p 矩陣 B 輸出:矩陣 C , C=A  B 1 將二維矩陣 A,B 的元素載入二維陣列 A,B 中: A[i][j]=a ij ;B[i][j]=b ij ; 2for (i=0; i

55 2.2.4 魔術方塊 15 8 1 24 17 8 1 6 16 14 7 5 23 3 5 7 22 20 13 6 4 4 9 2 3 21 19 12 10 9 2 25 18 11 (a)3 * 3 (b)5 * 5 當 n 是奇數時, H. Coxeter 觀察到了產生魔術 方塊的規則: – 填在第 1 列中間; – 將方塊想成上下、左右、對角相接的圓球,往左上 角填入下一個數字;若左上角已遭其它數字佔用, 則填在目前方格的下方。

56 程式 魔術方塊 1#define MaxSize = 21; 2int square[MaxSize][MaxSize]; 3void MagicSquare(int n) 4{ int i, j, k, l, data; 5 if ((n>MaxSize)||(n<1)) 6 { cerr<<” 輸入方塊過大,不予處理。 ”< { "@context": "http://schema.org", "@type": "ImageObject", "contentUrl": "http://images.slideplayer.com/16/4968364/slides/slide_56.jpg", "name": "程式 魔術方塊 1#define MaxSize = 21; 2int square[MaxSize][MaxSize]; 3void MagicSquare(int n) 4{ int i, j, k, l, data; 5 if ((n>MaxSize)||(n<1)) 6 { cerr<< 輸入方塊過大,不予處理。 <MaxSize)||(n<1)) 6 { cerr<< 輸入方塊過大,不予處理。 <

57 13while (data < n*n) 14 {k = (i-1<0) ? n-1 : i-1; 15 l = (j-1<0) ? n-1 : j-1; 16 if (square[k][l] > 0) i = (i+1)%n; 17 else {i = k; j = l; } 18 square[i][j] = data++; 19 } 20 cout< { "@context": "http://schema.org", "@type": "ImageObject", "contentUrl": "http://images.slideplayer.com/16/4968364/slides/slide_57.jpg", "name": "13while (data < n*n) 14 {k = (i-1<0) . n-1 : i-1; 15 l = (j-1<0) .", "description": "n-1 : j-1; 16 if (square[k][l] > 0) i = (i+1)%n; 17 else {i = k; j = l; } 18 square[i][j] = data++; 19 } 20 cout<

58 二維陣列之應用 ─ 數位影像

59 二維陣列之應用 ─ 老鼠走迷宮


Download ppt "陣列的抽象定義是一組具有相同資料 型態 (data type) 的元素,所組成 的有序集合 (ordered set) ,通常 儲存在一塊連續的記憶體上 。 陣列的應用技巧可開啟善用陣列資料 結構之門。 陣列在實體記憶空間中配置的關係可 引領各位瞭解陣列資料結構如何存放 在電腦中,以及程式語言、編譯器如."

Similar presentations


Ads by Google