Chapter 2 陣列結構 資料結構導論 - C語言實作
2.1 前言 「陣列」(Array)結構具有以下重要特徵: 一個陣列可以包含許多個陣列元素,陣列元素之個數又稱為陣列之大小。 同一個陣列裡的元素都具備相同的資料型態(Data Type)。 為方便資料的存取,可將陣列設計成一維(Dimension)、二維、三維,...,甚至更多維的陣列。 資料結構導論 - C語言實作
2.1 前言 宣告一個陣列時,作業系統會在記憶體空間指定一個起始位置給該陣列,並且根據陣列的資料型態和大小來配予一組連續的記憶體位置。 陣列元素在記憶體中的位置是連續且相鄰的,因此只要透過一套簡單的陣列元素位址計算公式,便能得知某陣列元素所在之記憶體位置。 經由陣列索引(Index),可以迅速且直接地存取陣列中的元素資料。 資料結構導論 - C語言實作
2.2 宣告陣列 宣告陣列時須定義下列幾項屬性: 陣列的資料型態。 陣列的名稱。 陣列的維度,即中括號([ ])的個數。 陣列每一維度的元素個數,亦即陣列大小。 陣列元素的初值,此項可以省略。 資料結構導論 - C語言實作
2.2 宣告陣列 以C語言為例,宣告陣列的語法如下: 資料結構導論 - C語言實作
2.2.1 一維陣列 【例1】宣告一個可以用來存放6次考試成績的整數陣列。 int grades[6] = {83, 75, 92, 74, 88, 93}; 資料結構導論 - C語言實作
2.2.2 二維陣列 【例2】宣告二維陣列。 資料結構導論 - C語言實作
2.2.2 二維陣列 【例3】宣告grades[50][6]為一個可以用來儲存50位同學之6次資料結構考試成績之二維陣列。 int grades[50][6] ; 資料結構導論 - C語言實作
2.3 陣列的表示法 一維陣列的表示法 二維陣列的表示法 三維陣列的表示法 多維度陣列的表示法 上三角矩陣 下三角矩陣 我們將「陣列」與「矩陣」視為同義詞 資料結構導論 - C語言實作
2.3.1 一維陣列的表示法 A[n] = {A[0],A[1],…,A[n-1]} 假設 則: 一維陣列A在記憶體的起始位置為α。 每個陣列元素所需的儲存空間是z個位元組(Byte) 。 陣列元素A[i]的記憶體位址為Loc(A[i]) 。 則: Loc(A[i]) = A的起始位址 + A[i]相對於陣列起始位置之位移 = α + i z。 資料結構導論 - C語言實作
2.3.1 一維陣列的表示法 【例1】設陣列A是一個大小為10的一維陣列,且陣列A在記憶體之起始位置為1000,且每個元素都需要2個位元組的儲存空間。則 A[7]的記憶體位置為何? 【解答】 Loc(A[7]) = A的起始位址 + A[7]相對於陣列起始位置之位移 = 1000 + 7 2 = 1014。 資料結構導論 - C語言實作
2.3.1 一維陣列的表示法 【例2】設d[100] 為一個實數陣列,每一個元素佔4個位元組。若d[10]的位址為2000,則d[88]的位址為何? 【解答】 Loc(d[88]) = d[10]的位址 + d[88]相對於d[10]之位移 = 2000 + (88-10) 4 = 2312。 資料結構導論 - C語言實作
2.3.1 一維陣列的表示法 A[f:t] = {A[f] ,A[f-1] ,... , A[0] , A[1] , ... ,A[t] } 。 假設 一維陣列A[f]在記憶體的起始位置為α。 每個陣列元素所需的儲存空間是z個位元組(Byte) 。 陣列元素A[i]的記憶體位址為Loc(A[i])。 則: Loc(A[i]) = A的起始位址 + A[i]相對於陣列起始位置之位移 = α + (i-f) z。 資料結構導論 - C語言實作
2.3.1 一維陣列的表示法 【例3】設A[-15:25]在記憶體的起始位置為123,且每一元素佔4個位元組,則A[3]的位址為何? 【解答】 Loc(A[3]) = A[-15:25]的起始位址 + A[3]相對於A[-15:25]之位移 = 123 + (3-(-15)) 4 = 195。 資料結構導論 - C語言實作
2.3.2 二維陣列的表示法 B[m][n] = {B[0][0],B[0][1],…, B[m-1][n-1] } 。 資料結構導論 - C語言實作
2.3.2 二維陣列的表示法 將二維的陣列元素轉換成一維排列的方式有下列兩種: 以列為主(Row Major) 。 以行為主(Column Major) 。 資料結構導論 - C語言實作
2.3.2 二維陣列的表示法 以列為主(Row Major)的表示法: 假設 則: 假設二維陣列B在記憶體的起始位置為α 。 陣列之個別元素所需的記憶體空間大小為z 。 陣列元素B[i][j]的記憶體位址為Loc(B[i][j]) 。 則: LocRM(B[i][j]) = B的起始位址 + B[i][j]相對於陣列起始位置之位移 = α + (i n + j) z 。 資料結構導論 - C語言實作
2.3.2 二維陣列的表示法 以行為主(Column Major)的表示法: 假設 則: 假設二維陣列B在記憶體的起始位置為α 。 陣列之個別元素所需的記憶體空間大小為z 。 陣列元素B[i][j]的記憶體位址為Loc(B[i][j]) 。 則: LocCM(B[i][j]) = B的起始位址 + B[i][j]相對於陣列起始位置之位移 = α + (j m + i) z 。 資料結構導論 - C語言實作
2.3.2 二維陣列的表示法 【例1】已知A[1][2]之記憶體位置為22,且A[2][4]和A[4][2] 之記憶體位置分別為30和40,則A[5][5]之位置為何? 【解答】 因為A[2][4]的記憶體位置30小於A[4][2] 的記憶體位置40,可見該陣列是採「以列為主」排列。因此: LocRM(A[i][j]) = A的起始位址 + A[i][j]相對於陣列起始位置之位移 = α + (i n + j) z。 資料結構導論 - C語言實作
2.3.2 二維陣列的表示法 LocRM(A[2][4]) = A[1][2]的位址 + A[2][4]相對於A[1][2]之位移 = 22 + ((2-1) n + (4-2)) z = 22 + (n + 2) z = 30。 所以,nz + 2z = 8 …………(1) LocRM(A[4][2]) = A[1][2]的位址 + A[4][2]相對於A[1][2]之位移 = 22 + ((4-1) n + (2-2)) z = 22 + (3n + 0) z = 40。 所以,3nz = 18 ,nz = 6 …………(2) ,將(2)代入(1)得到 6 + 2z = 8,z = 1,代入(2) 得到 n = 6 ,因此 資料結構導論 - C語言實作
2.3.2 二維陣列的表示法 LocRM(A[5][5]) = A[1][2]的位址 + A[5][5]相對於A[1][2]之位移 = 22 + ((5-1) n + (5-2)) z = 22 + (4 6 + 3) 1 = 49。 資料結構導論 - C語言實作
2.3.2 二維陣列的表示法 【例2】設A[f1:t1][f2:t2] 為一個二維陣列宣告,其記憶體起始位置為α,每個元素所佔的記憶體空間為z。則陣列元素A[i][j]之位置為何? 【解答】 已知A[f1][f2]在記憶體之起始位置為α,且每個元素所佔的記憶體空間為 z。 設二維陣列A共有m列n行,則 m = t1-f1+1, n = t2-f2+1。 資料結構導論 - C語言實作
2.3.2 二維陣列的表示法 以列為主 LocRM(A[i][j]) = A[f1][f2]的起始位址 + A[i][j]相對於A[f1][f2]之位移 = α + ((i-f1) n + (j-f2)) z 以行為主 LocCM(A[i][j]) = A[f1][f2]的起始位址 + A[i][j]相對於A[f1][f2]之位移 = α + ((j-f2) m + (i-f1)) z 資料結構導論 - C語言實作
2.3.3 三維陣列的表示法 int cubic[3][2][3] = { {1,2,3,4,5,6}, {7,8,9,1,2,3}, {4,5,6,7,8,9}}; 它包括3個平面,每個平面有2列及3行。 平面 列 行 資料結構導論 - C語言實作
2.3.3 三維陣列的表示法 假設我們宣告了一個三維陣列C[l][m][n] 假設 l 代表第一個維度的大小。 m 代表第二個維度的大小。 陣列之個別元素所需的記憶體空間大小為z 。 資料結構導論 - C語言實作
2.3.3 三維陣列的表示法 以列為主(Row Major)的表示法: 以行為主(Column Major)的表示法: 共計有 l 個平面,每個平面有 m 列與 n 行。 LocRM(C[i][j][k]) = α + (imn + jn + k) z 以行為主(Column Major)的表示法: 共計有 n 個平面,每個平面有 l 列與 m 行。 LocCM(C[i][j][k]) = α + (klm + jl + i) z 資料結構導論 - C語言實作
2.3.4 多維度陣列的表示法 假設 n 維度陣列D[s1][s2][s3]…[sn]在記憶體中的起始位置為α。 其中s1,s2,…,sn分別為D陣列的第1維、第2維,…,第n維的元素個數。 每個陣列元素所須要的記憶體儲存空間為z。 資料結構導論 - C語言實作
2.3.4 多維度陣列的表示法 以列為主(Row Major)的表示法: LocRM(D[i1][i2]…[in]) = α + (i1s2s3…sn-1sn + i2s3s4…sn-1sn + i3s4s5…sn-1sn + … + in-3sn-2sn-1sn + in-2sn-1sn + in-1sn + in) z 。 資料結構導論 - C語言實作
2.3.4 多維度陣列的表示法 以行為主(Column Major)的表示法: LocCM(D[i1][i2]…[in]) = α + (ins1s2…sn-2sn-1 + in-1s1s2…sn-3sn-2 + in-2s1s2…sn-4sn-3 + … + i3s1s2 + i2s1 + i1) z 。 資料結構導論 - C語言實作
2.3.5 對角線矩陣的表示法 對角線矩陣(Diagonal Matrix) 是一個「方陣」 。 除了對角線的元素值可能不為0外,其餘元素值均為0。 亦即,矩陣元素vi,j = 0,i ≠ j。 資料結構導論 - C語言實作
2.3.5 對角線矩陣的表示法 對角線矩陣(Diagonal Matrix) 對角線矩陣DM[m][m]共有m個非0元素。 我們可以直接用一個一維陣列X[m]來表示對角線矩陣。 亦即X[i]= DM[i][i]。 資料結構導論 - C語言實作
2.3.6 下三角矩陣的表示法 下三角矩陣(Lower Triangular Matrix) 它是一個「方陣」。 對角線以上(不含對角線)的元素值均為 0。 資料結構導論 - C語言實作
2.3.6 下三角矩陣的表示法 假設 採「以列為主」(row major) 的儲存策略,則 下三角矩陣式的陣列X在記憶體之起始位置為α。 且每個陣列元素所需的記憶體空間為z。 採「以列為主」(row major) 的儲存策略,則 LocRM(Xi,j)= + ((i(i+1))/2 + j) z 。 資料結構導論 - C語言實作
2.3.6 下三角矩陣的表示法 【例1】設X[n][n]為一個下三角矩陣,若要用一個一維陣列Y[m]來表示X,則m的最小值應該宣告為何? 【解答】 m = 1+2+3+...+n = n(n+1)/2。 資料結構導論 - C語言實作
2.3.7 上三角矩陣的表示法 上三角矩陣(Upper Triangular Matrix) 它是一個「方陣」。 對角線以下 (不含對角線)的元素值均為 0。 資料結構導論 - C語言實作
2.3.7 上三角矩陣的表示法 假設 採「以行為主」(column-major) 的儲存策略,則 下三角矩陣式的陣列X在記憶體之起始位置為α。 且每個陣列元素所需的記憶體空間為z。 採「以行為主」(column-major) 的儲存策略,則 LocCM(Xi,j)= + ((j(j+1))/2 + i) z 。 資料結構導論 - C語言實作
2.4 一維陣列的應用 2.4.1 計數器(Counter) 2.4.2 暫存(Temporary Store) 2.4.3 取代(Substitution) 2.4.4 索引(Indexing) 2.4.5 搜尋(Searching) 2.4.6 排序(Sorting) 資料結構導論 - C語言實作
2.4.1 計數器(Counter) i = i + 1; (或 i++; ) 。 int count[n]; //宣告 ... count[i] = count[i] + 1; //計數器 + 1 或 count[i]++ ; //計數器 + 1 資料結構導論 - C語言實作
2.4.2 暫存(Temporary Store) 「質數」:大於1的數,除了1與本身以外沒有任何一個數能夠整除它時,該數稱為質數。 2是最小的質數。 3、5、7均是質數。 4、6不是質數,因為4可以被2整除,6可以被2、3整除 。 資料結構導論 - C語言實作
2.4.2 暫存(Temporary Store) 如何找出小於等於100的所有質數呢? 第一種方法: 根據質數的定義,判斷5是否為質數時,須將5除以2、3、4,只要能被其中一個數整除,那麼5就非質數,否則5就是質數。 依此類推,判斷x是否為質數時,須將x除以2、3、4...、x-1,只要能被其中一個數整除,那麼x就非質數,否則x就是質數。 資料結構導論 - C語言實作
2.4.2 暫存(Temporary Store) 第二種方法: 將第1個找到的質數暫存於prime[0],將第2個找到的質數暫存於prime[1],將第3個找到的質數暫存於prime[2],依此類推。 要判斷一個整數x是否為質數時,我們只須取出prime陣列裡已經找到的質數來當做除數,將x除以這些質數,如果都不能被這些質數整除,即可斷定x為質數。 因此,要判斷6是否為質數時,只須分別判斷6是否能被2、3、5整除即可,只要能被其中一個質數整除,6就非質數。因6能被2整除,非質數,不須再判斷能否被3、5整除了。 資料結構導論 - C語言實作
2.4.3 取代(Substitution) 要印出 則可用陣列來儲存花色和點數以取代之 資料結構導論 - C語言實作
2.4.4 索引(Indexing) 「索引」:利用某一個陣列的元素值來當做另一個陣列的索引值。 尋找出眾數及其出現頻率 一維陣列x[15]是一個含有15個元素的整數陣列,且陣列中的元素值均介於0與5之間。我們稱陣列x中出現次數最多的數為「眾數」。 宣告一個整數陣列count[6],然後用count[i]來記錄x陣列中 i 的出現次數。 亦即 count[x[i]] = count[x[i]]++ ; 資料結構導論 - C語言實作
2.4.5 搜尋(Searching) 搜尋(Search):從一群資料中找出滿足特定條件的資料之動作稱之。 搜尋條件通常有: 大於、等於、小於、大於或等於、不等於、小於或等於等多種組合。 資料結構導論 - C語言實作
2.4.5.1 循序搜尋法(Sequential Search) 【例1】找出鍵值大於70的資料? 必須從d[0]開始逐筆加以比對,直到比完d[7]為止(共計比較8次) 結果找到d[2]、d[4]、d[5]、d[7]等4筆資料 資料結構導論 - C語言實作
2.4.5.2 二元搜尋法(Binary Search) 二元搜尋法的特徵如下: 資料須事先經過排序。 每次都從可能有符合條件的一組資料中,拿第中間筆資料(假設d[i])出來跟鍵值k相比。 每次比較完之後,大約可以捨去一半的資料,所以搜尋的速度很快。 資料結構導論 - C語言實作
2.4.5.2 二元搜尋法(Binary Search) 【例2】二元搜尋法。 找出鍵值等於120的資料? 資料結構導論 - C語言實作
2.4.5.2 二元搜尋法(Binary Search) 【例2】二元搜尋法。 找出鍵值大於70的資料? 資料結構導論 - C語言實作
2.4.6 排序(Sorting) 排序(SORT):乃將原始資料依照某個特定的次序加以重新排列。 排序時須指定: 用哪一個資料項來排序? 被用來排序的資料項又稱為「鍵(Key)」 排序的順序 遞增:即由小到大。 遞減:即由大到小。 資料結構導論 - C語言實作
2.4.6.1 氣泡浮昇排序法(Bubble Sort) 假設我們已經宣告了一個整數陣列d[n],用來存放編號為0、1、2、...、n-1的n筆資料。且 d[0] = v0、 d[1] = v1、 d[2] = v2、... d[n-2] = vn-2、 d[n-1] = vn-1。 資料結構導論 - C語言實作
2.4.6.1 氣泡浮昇排序法(Bubble Sort) 採用氣泡浮昇排序法的將一組資料依「鍵值遞增」排序之步驟說明如下: 第1回合: 從第0筆資料開始一直到第n-1筆資料,持續比較相鄰兩筆資料之大小,若vi大於vi+1,則須將兩者交換位置,亦即須將vi 儲存到d[i+1],vi+1 儲存到d[i]。換言之,必須保持小的在前,大的在後之順序。 在第1回合處理完後,陣列中最大的數值已經被存放到d[n-1]的位置。 資料結構導論 - C語言實作
2.4.6.1 氣泡浮昇排序法(Bubble Sort) 第2回合: 從第0筆資料開始一直到第n-2筆資料,持續比較相鄰兩筆資料之大小,若vi大於vi+1,則須將兩者交換位置,亦即須將vi 儲存到d[i+1],vi+1 儲存到d[i]。 在第2回合處理完後,陣列中第2大數的值已經被存放到d[n-2]的位置。 重複執行上述步驟,共計(n-1)回合,即可將陣列資料排列成由小到大的遞增順序。 資料結構導論 - C語言實作
2.4.6.1 氣泡浮昇排序法(Bubble Sort) 【例2】氣泡浮昇排序法。 資料結構導論 - C語言實作
2.4.6.1 氣泡浮昇排序法(Bubble Sort) 【例2】氣泡浮昇排序法。 資料結構導論 - C語言實作
2.5 二維陣列的應用 2.5.1 轉置矩陣(Transpose Matrix) 2.5.2 對稱矩陣(Symmetric Matrix) 2.5.3 反射矩陣(Reflection Matrix) 2.5.4 矩陣相加(Matrix Addition) 2.5.5 矩陣相減(Matrix Subtraction) 2.5.6 矩陣乘積(Matrix Multiplication) 2.5.7 稀疏矩陣(Sparse Matrix) 資料結構導論 - C語言實作
2.5.1 轉置矩陣(Transpose Matrix) 設M是一個mn矩陣,而TM為其轉置矩陣,則: TM為一個nm矩陣。 M的第0列元素成為TM的第0行元素, M的第1列元素成為TM的第1行元素,…, M的第m-1列元素成為TM的第m-1行元素。 亦即 TM[j][i] = M[i][j]。 資料結構導論 - C語言實作
2.5.1 轉置矩陣(Transpose Matrix) 【例1】轉置矩陣。 資料結構導論 - C語言實作
2.5.2 對稱矩陣(Symmetric Matrix) 對稱矩陣為一方陣,且元素值vij = vji。 資料結構導論 - C語言實作
2.5.3 反射矩陣(Reflection Matrix) 反射矩陣(RMmxn)是將原始矩陣(Mmxn)進行水平方向的鏡射。 資料結構導論 - C語言實作
2.5.4 矩陣相加(Matrix Addition) cij=aij+bij。 【例1】矩陣相加。 資料結構導論 - C語言實作
2.5.5 矩陣相減(Matrix Subtraction) cij=aij-bij。 【例1】矩陣相減。 資料結構導論 - C語言實作
2.5.6 矩陣乘積(Matrix Multiplication)
2.5.6 矩陣乘積(Matrix Multiplication) 【例1】矩陣乘積。 資料結構導論 - C語言實作
2.5.7 稀疏矩陣(Sparse Matrix) 一個矩陣中,若大多數的元素值均為0,則稱該矩陣為「稀疏矩陣」。 這裡所謂的元素值為0在應用上包括幾種涵義: 真的為0。 為虛值(Null Value) ,亦即沒有資料值 資料結構導論 - C語言實作
2.5.7 稀疏矩陣(Sparse Matrix) 【例1】稀疏矩陣的表示法。 資料結構導論 - C語言實作
2.5.7 稀疏矩陣(Sparse Matrix) 【例2】試設計一個用以表示三維稀疏矩陣的表示法。 【解答】設三維稀疏矩陣SMmxnxo各維之大小 分別為m、n、o,且稀疏矩陣中非0元素 共計p個。 資料結構導論 - C語言實作