1 / 37

第 2 章 陣列結構與矩陣

第 2 章 陣列結構與矩陣. 線性串列的定義 多項式的抽象資料型態應用 認識陣列 矩陣的應用 字串與字元陣列應用 字串運算處理. 線性串列的特性 (1). 2-1 線性串列的定義. 定義「線性串列」 (Linear List) :. 1. 存在的唯一的第一個元素 2. 存在唯一的最後一個元素 3. 除第一個元素外,每一個元素都有一個唯一的前相鄰元素 4. 除了最後一個元素之外,每一個元素都有一個唯一的後相鄰元素. 線性串列的特性 (2). 2-1 線性串列的定義. 線性串列包含了以下 9 種運算方式:.

yule
Download Presentation

第 2 章 陣列結構與矩陣

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第2章 陣列結構與矩陣 線性串列的定義 多項式的抽象資料型態應用 認識陣列 矩陣的應用 字串與字元陣列應用 字串運算處理

  2. 線性串列的特性(1) 2-1 線性串列的定義 • 定義「線性串列」(Linear List): 1.存在的唯一的第一個元素 2.存在唯一的最後一個元素 3.除第一個元素外,每一個元素都有一個唯一的前相鄰元素 4.除了最後一個元素之外,每一個元素都有一個唯一的後相鄰元素

  3. 線性串列的特性(2) 2-1 線性串列的定義 • 線性串列包含了以下9種運算方式: 1.取出串列中的第i項;1≦i≦n 2.計算串列的長度n 3.由左至右,或由右至左讀此串列 4.加入一個新值到第i項,使得原來的第i,i+1……n變為第 i+1,i+2,……,n+1項 5.刪除位於第i項的一個元素,使原來的i+1,i+2,…項,變成第i,i +1,……,n-1項 6.複製串列 7.合併串列 8.分割串列 9.從兩端逐個讀取串列的元素值

  4. 一維陣列(1) 2-2 認識陣列 • 宣告格式如下: • 以下舉出C中幾個一維陣列的宣告實例: 資料型態 陣列名稱[陣列長度]; int a[5];/*宣告一個int型態的陣列a,陣列a中可以存放5個int型態的資料*/ long b[3];/*宣告一個long型態的陣列b,陣列b可以存放3個long型態的資料*/ float c[10];/*宣告一個float型態的陣列c,陣列c可以存放10個float型態的資料*/

  5. 一維陣列(2) 2-2 認識陣列 • 範例程式:ch02_01.c

  6. 2-2 認識陣列 執行結果

  7. 二維陣列(1) 2-2 認識陣列 • 宣告格式如下: • 例如宣告陣列A的列數是2,行數是3,所有元素個數為6。格式如下所示: • 陣列中元素的分佈圖說明如下: 資料型態 陣列名稱 [m] [n]; int A [2] [3];

  8. 二維陣列(2) 2-2 認識陣列 • 範例程式:ch02_02.c

  9. 2-2 認識陣列

  10. 2-2 認識陣列 • 執行結果

  11. 二維陣列(3) 2-2 認識陣列 • 以列為主(Row-Major),如C、C++、Java語言 • 即為A(1,1)、A(1,2)、…A(1,n)、…A(m,n),且所在位址的計算公式: • 以行為主(Column-Major),如Fortran語言 • 即為A(1,1)、A(2,1)、……A(m,1)、A(1,2)…A(m,n),則位址計算公式: Loc(A(i,j))=α+n*(i-1)*d +(j-1)*d (d為每單位空間,α為起始位址) Loc(A(i,j))=α+(i-1)*d+m*(j-l)*d

  12. 2-2 認識陣列 • 假設α仍為起始位址,而且m=(u1-l1+1),n=(u2-l2+1)。則有下列公式: • 以列為主(Row-Major): • 以行為主(Column-Major): Loc A(i,j)=α+((i-l1+1)-1)*n*d+((j-l2+1)-1)*d Loc A(i,j)=α+((j-l2+1)-1)*m*d+((i-l1+1)-1)*d

  13. 二維陣列(4) 2-2 認識陣列 • 範例2.2.1 • 陣列(Array)被以橫列(Row)為主的順序存放在記憶體內,每個陣列元素佔用4個單位的記憶體。若起始位址是100,在下列宣告中,所列元素存放位置為何? • 1.VarA=array[-100…1,1…100],求A[1,12]之位址。 • 2.VarA=array[5…10,-10…20],求A[5,-5]之位址。 • 範例2.2.2 • 有一個二維陣列A,已知a3,2的位址為1110,a2,3的位址為1115,且每個元素佔一個位址,則a5,4的位址為何? • 範例2.2.3 • A(-3:5,-4:2)之起始位址A(-3,-4)=100,以列為主排列,請問A(1,1)所在位址?(d=1)

  14. 多維陣列(1) 2-2 認識陣列 • 宣告格下如下: • 例如:宣告一個int型態的三維陣列A 資料型態 陣列名稱[N1][N2][N3]; int A[2][2][2]={{ {1,2}, {5,6} }, { {3,4}, {7,8﹜ }};

  15. 多維陣列(2) 2-2 認識陣列 • 以列為主(Row-Major) • 可以將陣列A視為u1個u2*u3的二維列陣,再將每個陣列視為有u2個一維陣列,每一個一維陣列可包含u3的元素。 • 位址計算公式: Loc(A(i,j,k))=α+(i-1)u2u3d+(j-1)u3d+(k-1)d

  16. 多維陣列(3) 2-2 認識陣列 • 以行為主(Column-Major) • 將陣列A視為u3個u2*u1的二為陣列,再將每個二維陣列視為有u2個一維陣列,每一陣列含有u1個元素。 • 若陣列宣告為A(l1:u1,l2:u2,l3:u3),則 a= u1- l1+1,b= u2- l2+1,c= u3- l3+1; Loc(A(i,j,k))=α+(k-l3)abd+(j-l2)ad+(i-l1)d

  17. 多維陣列(4) 2-2 認識陣列 • 範例2.2.4 • 假設有A(1:3,1:4,1:5)陣列,且Loc(A(1,1,1))=100,請求出以列為主排列的Loc(A(1,2,3))=? • 範例2.2.5 • 有一個三維陣列A(-3:2,-2:3,0:4),以Row-Major方式排列,陣列之起始位址是318,試求Loc(A(1,3,3))=?(每個元素佔一空間) • 範例2.2.6 • A(6,4,2)是以列為主方式排列,若α=300,且d=1,求A(4,4,1)的位址。

  18. 矩陣的運算(1) 2-3 矩陣的應用 • 矩陣相加 • 首先必須符合A為一個m*n的矩陣,B為一個n*p的矩陣,對A*B之後的結果為一個m*p的矩陣C。 C11= a11 * b11+ a12* b21+………+ a1n* bn1 : : C1p= a11* b1p+ a12* b2p+……+ a1n*bnp : : Cmp= am1* b1p+am2* b2p+………+ amn* bnp

  19. 矩陣的運算(2) 2-3 矩陣的應用 • 範例程式:ch02_03.c 01/********************************* 02 *程式檔名:ch02_03.c 03 *程式功能:兩個矩陣相加 04 *********************************/ 05#include <stdio.h> 06#include <stdlib.h> 07#define ROWS 2 08#define COLS 2 09/*矩陣內容列印副程式*/ 10void PrintMatrix(int* arrA) 11{ 12int i,j; 13for(i=0;i<ROWS;i++) 14 { 15 for(j=0;j<COLS;j++) 16 printf("%d\t",arrA[i*COLS+j]); 17 printf("\n"); 18} 19} 20/*矩陣內容相加副程式*/ 21void MatrixAdd(int* arrA,int* arrB,int* arrC,int dimX,int dimY) 22{

  20. 2-3 矩陣的應用 23 int row,col; 24 if(dimX<=0||dimY<=0) 25 { 26 printf("矩陣維數必須大於0\n"); 27 return; 28 } 29 for(row=1;row<=dimX;row++) 30 for(col=1;col<=dimY;col++) 31 arrC[(row-1)*dimY+(col-1)]=arrA[(row-1)*dimY+(col-1)]+arrB[(row-1)*dimY+(col-1)]; 32} 33 34int main(void) 35{ 36int A[ROWS][COLS] = {{15,35},{12,23}}; 37 int B[ROWS][COLS] = {{24,17},{36,51}}; 38 int C[ROWS][COLS] = {0}; 39 printf("矩陣A的各個元素===\n"); /*印出矩陣A的內容*/ 40 PrintMatrix(&A[0][0]); 41 printf("矩陣B的各個元素===\n"); /*印出矩陣B的內容*/ 42 PrintMatrix(&B[0][0]); 43 MatrixAdd(&A[0][0],&B[0][0],&C[0][0],ROWS,COLS); 44 printf("矩陣A和矩陣B相加===\n"); /*印出A+B的內容*/ 45 PrintMatrix(&C[0][0]); 46 system("pause"); 47}

  21. 2-3 矩陣的應用 • 程式執行結果

  22. 矩陣的運算(3) 2-3 矩陣的應用 • 矩陣相乘 • 首先必須符合A為一個m*n的矩陣,B為一個n*p的矩陣,對A*B之後的結果為一個m*p的矩陣C。 C11= a11 * b11+ a12* b21+………+ a1n* bn1 : : C1p= a11* b1p+ a12* b2p+……+ a1n*bnp : : Cmp= am1* b1p+am2* b2p+………+ amn* bnp

  23. 矩陣的運算(4) 2-3 矩陣的應用 • 範例程式:ch02_04.c • 01/********************************* • 02 *程式檔名:ch02_04.c • 03 *程式功能:兩個矩陣相乘 • 04 *********************************/ • 05#include <stdio.h> • 06#include <stdlib.h> • 07#include <conio.h> • 08#define MSize 2 • 09#define NSize 3 • 10#define PSize 2 • 11/*矩陣內容列印副程式*/ • 12void PrintMatrix(int* arrA,int rows,int cols) • 13{ • int i,j; • 15for(i=0;i<rows;i++)

  24. 2-3 矩陣的應用 • 16{ • 17for(j=0;j<cols;j++) • 18printf("%d\t",arrA[i*cols+j]); • 19printf("\n"); • 20} • 21} • 22/*矩陣內容相乘副程式*/ • 23void MatrixMultiply(int* arrA,int* arrB,int* arrC,int M,int N,int P) • 24{ • 25int i,j,k,Temp; • 26if(M<=0||N<=0||P<=0) • 27{ • 28printf("[錯誤:維數M,N,P必須大於0]\n"); • 29return; • 30} • 31for(i=0;i<M;i++) • for(j=0;j<P;j++) • 33{ • Temp = 0; • 35for(k=0;k<N;k++)

  25. 2-3 矩陣的應用 36Temp = Temp + arrA[i*N+k]*arrB[k*P+j]; 37arrC[i*P+j] = Temp; 38} 39} 40 41int main(void) 42{ 43int A[MSize][NSize] = {{1,1,1},{2,2,2}}; 44int B[NSize][PSize] = {{2,3},{4,5},{6,7}}; 45int C[MSize][PSize] = {0}; 46printf("矩陣A的各個元素===\n"); /*印出矩陣A的內容*/ 47PrintMatrix(&A[0][0],MSize,NSize); 48printf("矩陣B的各個元素===\n"); /*印出矩陣B的內容*/ 49PrintMatrix(&B[0][0],NSize,PSize); 50MatrixMultiply(&A[0][0],&B[0][0],&C[0][0],MSize,NSize,PSize); 51printf("矩陣A和矩陣B相乘===\n");/*印出A*B的內容*/ 52PrintMatrix(&C[0][0],MSize,PSize); 53system("pause"); 54}

  26. 2-3 矩陣的應用 • 程式執行結果

  27. 矩陣的運算(5) 2-3 矩陣的應用 • 轉置矩陣 • 「轉置矩陣」(At)就是把原矩陣的行座標元素與列座標元素相互調換,假設At為A的轉置矩陣,則有At[j,i]=A[i,j]如下所示:

  28. 稀疏矩陣 2-3 矩陣的應用 • 在一個稀疏矩陣中,若共有t個非零項,則利用一個A(0:t,1:3)的二維陣列來表示,其中A(i,1)表列數、A(i,2)表行數、A(i,3)表示非零項的值(0≦i≦t)。 • 範例 2.3.1 • 試舉例說明兩個稀疏矩陣的乘積不再是稀疏矩陣。

  29. 字元陣列的應用 2-4 字串與字元陣列應用 • 例如在C中宣告一個長度為10字元的字元陣列arr2。如下所示: • 字元型態的資料會佔用記憶體1byte的空間,因此上述字元陣列一共佔用了記憶體10bytes的空間。 • 通常字元陣列會應用在字串的處理上,例如要將字串「tomguns」存入字元陣列。 char arr2[10]; char arr2[8]= "tomguns";

  30. 字串陣列與二維陣列 2-4 字串與字元陣列應用 • 字串陣列宣告方式如下: • 其中字串數是表示此字串陣列容納最多的字串數目,而字元數是表示每個字串大小最多可容納多少字元,並且包含了\0結尾字元。例如: char 字串陣列名稱[字串數][字元數]; char arr[3][8]=﹛﹛"tomguns"﹜, ﹛"sandy"﹜, ﹛"kelly"﹜﹜

  31. 2-4 字串與字元陣列應用 • 上述字串陣列方式如下圖所示: • 如果要使用二維陣列arr內字串「sandy」的「d」字元時,那麼就要將索引值指定到「arr[1][3]」: arr[2]→"kelly" arr[1][3]→"d"

  32. 字串長度與複製 2-5 字串運算處理 • 以下是字串長度與複製的C部份演算法: 01for(i=0; str[i]!='\0';i++) 02{ 03str1[i]=str[i];/* 逐一字元拷貝 */ 04} 05str1[i]=‘\0’;/* 在計算字串長度時,並不包含字串結    尾字元'\0' */ 06printf("此字串有%d個字元\n",i); 07printf("原字串str=%s\n",str); 08printf("複製後字串str1=%s\n",str1);

  33. 字串連結 2-5 字串運算處理 • 以下是字串連結的C部份演算法: 01for (count=0; Str_1[count] != ‘\0’; count++, s_record++) /* 將 Str_1 字串複製到 Str_3 */ 02Str_3[s_record]=Str_1[count]; 03for (count=0; Str_2[count] != ‘\0’; count++, s_record++) /* 將 Str_2 字串複製到 Str_3 */ 04Str_3[s_record]=Str_2[count]; 05Str_3[s_record]='\0'; /* 字串最後要加上 NULL 字元 */ 06printf(“連結後的字串 Str_3:%s”, Str_3); /* 顯示字串連   結的結果 */

  34. 字串比較 2-5 字串運算處理 • 以下是字串比較的C部份演算法: 01for (count=0; Str_1[count] != '\0' && Str_2[count] != '\0'; count++) 02if ( Str_1[count] == Str_2[count] ) 03continue; /* 相等則繼續比較下一個字元 */ 04else 05break; /* 不相等即跳出迴圈的執行 */ 06if ( Str_1[count] == ‘\0’ && Str_2[count] == ‘\0’ ) /* 判   斷兩個字串是否都比較到結尾字元 */ 07printf("2個字串相等..."); /* 顯示結果 */ 08else 09printf("2個字串不相等..."); /* 顯示結果 */

  35. 多項式的定義(1) 2-6 多項式的抽象資料型態應用 • 通常多項式在電腦中的表示法可用線性循環串列(如陣列)或鏈結串列來表示。 • 而利用陣列表示法有以下兩種: • 1.不考慮P是否含有零項次,而利用一個n+2長的陣列,以指數大小儲存,陣列的第一元素是代表最大的指數,例如A(1:n+2)=(n,an,an-1,…a1,a0) 優點:相關演算法簡單。 缺點:對於某些多項式而言,太浪費空間,如X10000+1,用此方法需要長度10002,=>A=(10000,1,0,0,……,0,1)。

  36. 多項式的定義(2) 2-6 多項式的抽象資料型態應用 • 2.只考慮多項式的非零項項目數目,若有m項,則用一個2m+1長的陣列,分別儲存每一個非零的指數和係數,而此陣列的第一個元素是多項式非零項的個數。 優點:避免空間浪費。 缺點:相關演算法較為複雜。(如多項式的加法演算)。

  37. 多項式的加法運算 2-6 多項式的抽象資料型態應用 • 對於多項式的相關演算法而言,最典型的就是加法運算。 • 基本上,兩多項式A、B相加的原理很簡單。 • 將A(X)和B(X)逐項相加,並在比較時以下列三種狀況來區分: ①A指數=B指數 ②A指數>B指數 ③A指數<B指數

More Related