4.2.1 矩陣的數(shù)組表示
【數(shù)據(jù)結(jié)構(gòu)】數(shù)組和字符串(一):矩陣的數(shù)組表示
4.2.2 特殊矩陣的壓縮存儲
??矩陣是以按行優(yōu)先次序?qū)⑺芯仃囋卮娣旁谝粋€一維數(shù)組中。但是對于特殊矩陣,如對稱矩陣、三角矩陣、對角矩陣和稀疏矩陣等, 如果用這種方式存儲,會出現(xiàn)大量存儲空間存放重復信息或零元素的情況,這樣會造成很大的空間浪費。為節(jié)約存儲空間和算法(程序)運行時間,通常會采用壓縮存儲的方法。
- 對角矩陣:指除了主對角線以外的元素都為零的矩陣,即對 任意 i ≠ j (1≤ i , j ≤n),都有M(i, j)=0。由于只有主對角線上有非零元素,只需存儲主對角線上的元素即可。
- 三角矩陣:指上三角或下三角的元素都為零的矩陣。同樣地,只需存儲其中一部分非零元素,可以節(jié)省存儲空間。
- 對稱矩陣:指矩陣中的元素關(guān)于主對角線對稱的矩陣。由于對稱矩陣的非零元素有一定的規(guī)律,可以只存儲其中一部分元素,從而減少存儲空間。
- 稀疏矩陣:指大部分元素為零的矩陣。傳統(tǒng)的按行優(yōu)先次序存儲方法會浪費大量空間來存儲零元素,因此采用壓縮存儲的方法更為合適。常見的壓縮存儲方法有:壓縮稠密行(CSR)、壓縮稠密列(CSC)、坐標列表(COO)等。
a. 對角矩陣的壓縮存儲
【數(shù)據(jù)結(jié)構(gòu)】數(shù)組和字符串(二):特殊矩陣的壓縮存儲:對角矩陣——一維數(shù)組
b. 三角矩陣的壓縮存儲
??三角矩陣分為上三角矩陣和下三角矩陣。方陣M是上三角矩陣,當且僅當i > j時有M(i, j)=0 . 方陣M是下三角矩陣,當且僅當i < j時有M(i,j)=0 。這里以下三角矩陣為例,討論其壓縮存儲方法:
??考慮一個n×n維下三角矩陣,其第一行至多有1個非零元素,第二行至多有2個非零元素,……,第n行至多有n個非零元素,非零元素至多共有(1+2+…+n) = n(n+1)/2個。可以用大小為n(n+1)/2的一維數(shù)組來存儲下三角矩陣,換言之,就是要把下三角矩陣M的非零元素映射到一個一維數(shù)組d中。映射次序可采用按行優(yōu)先或按列優(yōu)先。
- 假設(shè)映射采取按行優(yōu)先,非零元素M(i, j)會映射到一維數(shù)組d中的哪個元素?
- 設(shè)元素M(i, j)前面有k個非零元素,則k可計算如下:
- k = 1+2+…+(i-1)+(j-1)= i(i-1)/2+j-1
- 設(shè)元素M(i, j)前面有k個非零元素,則k可計算如下:
- 假設(shè)映射采取按列優(yōu)先,非零元素M(i, j)會映射到一維數(shù)組d中的哪個元素?
結(jié)構(gòu)體
typedef struct {
int size; // 矩陣的維度
int elements[MAX_SIZE]; // 存儲下三角元素的數(shù)組
} LowerTriangularMatrix;
??結(jié)構(gòu)體 LowerTriangularMatrix
,包含兩個成員變量:size
表示矩陣的維度,elements
是一個一維數(shù)組,用于存儲下三角矩陣的元素。接下來,代碼實現(xiàn)了幾個函數(shù)來進行下三角矩陣的初始化、元素設(shè)置、元素獲取以及打印矩陣的操作。
初始化
void initialize(LowerTriangularMatrix *matrix, int size) {
matrix->size = size;
// 初始化下三角元素數(shù)組
for (int i = 0; i < size * (size + 1) / 2; i++) {
matrix->elements[i] = 0;
}
}
??initialize
函數(shù)用于初始化下三角矩陣,接受一個指向 LowerTriangularMatrix
結(jié)構(gòu)體的指針以及矩陣的維度作為參數(shù)。它將矩陣的維度存儲在 size
成員變量中,并將 elements
數(shù)組中的所有元素初始化為 0。
元素設(shè)置
void setElement(LowerTriangularMatrix *matrix, int row, int col, int value) {
if (row < col) {
printf("Error: Only elements in or below the main diagonal can be set.\n");
} else if (row < 0 || row >= matrix->size || col < 0 || col >= matrix->size) {
printf("Error: Invalid row or column index.\n");
} else {
int index = row * (row + 1) / 2 + col; // 計算壓縮存儲的索引
matrix->elements[index] = value;
}
}
?? setElement
函數(shù)用于設(shè)置下三角矩陣中指定位置的元素值。
- 它接受一個指向
LowerTriangularMatrix
結(jié)構(gòu)體的指針,以及要設(shè)置的元素的行、列索引和值作為參數(shù)。 - 在設(shè)置元素之前,它會進行一些錯誤檢查,例如判斷行列索引是否有效以及是否在下三角矩陣的主對角線或以下。如果檢查通過,它會計算出在壓縮存儲中的索引,并將指定位置的元素值設(shè)置為給定的值。
元素獲取
int getElement(LowerTriangularMatrix *matrix, int row, int col) {
if (row < 0 || row >= matrix->size || col < 0 || col >= matrix->size) {
printf("Error: Invalid row or column index.\n");
return 0;
} else if (row < col) {
return 0;
} else {
int index = row * (row + 1) / 2 + col; // 計算壓縮存儲的索引
return matrix->elements[index];
}
}
??getElement
函數(shù)用于獲取下三角矩陣中指定位置的元素值。
- 它接受一個指向
LowerTriangularMatrix
結(jié)構(gòu)體的指針,以及要獲取的元素的行、列索引作為參數(shù)。 - 在獲取元素之前,它也會進行行列索引的有效性檢查。
- 如果索引無效,它會打印錯誤消息并返回 0。
- 如果指定位置在下三角矩陣的主對角線或以下,它會計算出在壓縮存儲中的索引,并返回相應的元素值。
- 如果指定位置在主對角線以上,表示該位置應為零,因此直接返回 0。
打印矩陣
void printMatrix(LowerTriangularMatrix *matrix) {
for (int i = 0; i < matrix->size; i++) {
for (int j = 0; j < matrix->size; j++) {
printf("%d ", getElement(matrix, i, j));
}
printf("\n");
}
}
??printMatrix
函數(shù)用于打印下三角矩陣。函數(shù)使用嵌套的循環(huán)遍歷矩陣的所有行和列。對于每個位置,如果行索引大于等于列索引,表示該位置存在元素,需要打印 elements
數(shù)組中對應的值;否則,表示該位置不存在元素,打印 0。打印完一行后,換行繼續(xù)打印下一行。
主函數(shù)
int main() {
LowerTriangularMatrix matrix;
int size = 4;
initialize(&matrix, size);
setElement(&matrix, 0, 0, 1);
setElement(&matrix, 1, 0, 2);
setElement(&matrix, 1, 1, 3);
setElement(&matrix, 2, 0, 4);
setElement(&matrix, 2, 1, 5);
setElement(&matrix, 2, 2, 6);
setElement(&matrix, 3, 0, 7);
setElement(&matrix, 3, 1, 8);
setElement(&matrix, 3, 2, 9);
setElement(&matrix, 3, 3, 10);
printf("Lower Triangular Matrix:\n");
printMatrix(&matrix);
return 0;
}
??在 main
函數(shù)中,首先創(chuàng)建了一個 LowerTriangularMatrix
結(jié)構(gòu)體變量 matrix
,并指定矩陣的維度為 4。然后,通過調(diào)用 initialize
函數(shù)初始化了矩陣。接下來,通過多次調(diào)用 setElement
函數(shù)設(shè)置了矩陣中的各個元素的值。最后,調(diào)用 printMatrix
函數(shù)打印了下三角矩陣的內(nèi)容。
輸出結(jié)果
代碼整合
#include <stdio.h>
#define MAX_SIZE 100
// 定義下三角矩陣結(jié)構(gòu)體
typedef struct {
int size; // 矩陣的維度
int elements[MAX_SIZE]; // 存儲下三角元素的數(shù)組
} LowerTriangularMatrix;
// 初始化下三角矩陣
void initialize(LowerTriangularMatrix *matrix, int size) {
matrix->size = size;
// 初始化下三角元素數(shù)組
for (int i = 0; i < size * (size + 1) / 2; i++) {
matrix->elements[i] = 0;
}
}
// 設(shè)置下三角矩陣中指定位置的元素值
void setElement(LowerTriangularMatrix *matrix, int row, int col, int value) {
if (row < col) {
printf("Error: Only elements in or below the main diagonal can be set.\n");
} else if (row < 0 || row >= matrix->size || col < 0 || col >= matrix->size) {
printf("Error: Invalid row or column index.\n");
} else {
int index = row * (row + 1) / 2 + col; // 計算壓縮存儲的索引
matrix->elements[index] = value;
}
}
// 獲取下三角矩陣中指定位置的元素值
int getElement(LowerTriangularMatrix *matrix, int row, int col) {
if (row < 0 || row >= matrix->size || col < 0 || col >= matrix->size) {
printf("Error: Invalid row or column index.\n");
return 0;
} else if (row < col) {
return 0;
} else {
int index = row * (row + 1) / 2 + col; // 計算壓縮存儲的索引
return matrix->elements[index];
}
}
// 打印下三角矩陣
void printMatrix(LowerTriangularMatrix *matrix) {
for (int i = 0; i < matrix->size; i++) {
for (int j = 0; j < matrix->size; j++) {
printf("%d ", getElement(matrix, i, j));
}
printf("\n");
}
}
int main() {
LowerTriangularMatrix matrix;
int size = 4;
initialize(&matrix, size);
setElement(&matrix, 0, 0, 1);
setElement(&matrix, 1, 0, 2);
setElement(&matrix, 1, 1, 3);
setElement(&matrix, 2, 0, 4);
setElement(&matrix, 2, 1, 5);
setElement(&matrix, 2, 2, 6);
setElement(&matrix, 3, 0, 7);
setElement(&matrix, 3, 1, 8);
setElement(&matrix, 3, 2, 9);
setElement(&matrix, 3, 3, 10);
printf("Lower Triangular Matrix:\n");
printMatrix(&matrix);
return 0;
}
c. 對稱矩陣的壓縮存儲
??n×n方陣M是對稱矩陣,當且僅當對任意 i , j (1≤ i , j ≤ n),均有M(i, j) = M( j, i) 。
??因為對稱矩陣中M(i, j)與M(j, i)的信息相同,所以只需存儲其上三角部分或下三角部分的元素信息。這里參照下三角矩陣的壓縮存儲方法,即用大小為n(n+1)/2的一維數(shù)組來存儲,關(guān)于對稱矩陣中的下三角部分的元素M(i, j) (i ≥ j) ,與下三角矩陣壓縮存儲的映射公式一樣,映射到d[k](其中k= i(i-1)/2+( j-1) );關(guān)于對稱矩陣之上三角部分的元素M(i, j)(i< j,不包含對角線上的元素),因其元素值與下三角部分的M(j, i)相同,故應映射到下標為q的元素d[q]中(其中q=j(j-1)/2+(i-1) )。 有了k和q的計算公式,即可實現(xiàn)對稱矩陣的壓縮存儲。
??要實現(xiàn)對稱矩陣的壓縮存儲,只需要在上述下三角矩陣的壓縮存儲上稍作修改即可:
元素設(shè)置
void setElement(SymmetricMatrix *matrix, int row, int col, int value) {
if (row < 0 || row >= matrix->size || col < 0 || col >= matrix->size) {
printf("Error: Invalid row or column index.\n");
} else {
// 交換行和列的位置,確保 row <= col
if (row > col) {
int temp = row;
row = col;
col = temp;
}
int index = row * matrix->size + col - (row * (row + 1) / 2); // 計算壓縮存儲的索引
matrix->elements[index] = value;
}
}
??setElement
函數(shù)用于設(shè)置對稱矩陣中指定位置的元素值。
- 在設(shè)置元素之前,會進行一些邊界檢查,并通過交換行和列的位置,確保 row <= col。
- 然后根據(jù)壓縮存儲的方式計算出對應位置在
elements
數(shù)組中的索引,并將值賦給該位置的元素。
元素獲取
int getElement(SymmetricMatrix *matrix, int row, int col) {
if (row < 0 || row >= matrix->size || col < 0 || col >= matrix->size) {
printf("Error: Invalid row or column index.\n");
return 0;
} else {
// 交換行和列的位置,確保 row <= col
if (row > col) {
int temp = row;
row = col;
col = temp;
}
int index = row * matrix->size + col - (row * (row + 1) / 2); // 計算壓縮存儲的索引
return matrix->elements[index];
}
}
??getElement
函數(shù)用于獲取對稱矩陣中指定位置的元素值。文章來源:http://www.zghlxwxcb.cn/news/detail-720432.html
- 同樣進行邊界檢查,并通過交換行和列的位置,確保 row <= col。
- 然后根據(jù)壓縮存儲的方式計算出對應位置在
elements
數(shù)組中的索引,并返回相應位置的元素值。
主函數(shù)
int main() {
SymmetricMatrix matrix;
int size = 4; // 假設(shè)對稱矩陣的維度為4
initialize(&matrix, size);
// 設(shè)置對稱矩陣的元素值
setElement(&matrix, 0, 0, 1);
setElement(&matrix, 1, 1, 2);
setElement(&matrix, 2, 2, 3);
setElement(&matrix, 1, 0, 4);
setElement(&matrix, 2, 0, 5);
setElement(&matrix, 2, 1, 6);
// 打印對稱矩陣
printMatrix(&matrix);
return 0;
}
輸出結(jié)果
文章來源地址http://www.zghlxwxcb.cn/news/detail-720432.html
代碼整合
#include <stdio.h>
#define MAX_SIZE 100
// 定義對稱矩陣結(jié)構(gòu)體
typedef struct {
int size; // 矩陣的維度
int elements[MAX_SIZE]; // 存儲對稱矩陣元素的數(shù)組
} SymmetricMatrix;
// 初始化對稱矩陣
void initialize(SymmetricMatrix *matrix, int size) {
matrix->size = size;
// 初始化對稱矩陣元素數(shù)組
for (int i = 0; i < size * (size + 1) / 2; i++) {
matrix->elements[i] = 0;
}
}
// 設(shè)置對稱矩陣中指定位置的元素值
void setElement(SymmetricMatrix *matrix, int row, int col, int value) {
if (row < 0 || row >= matrix->size || col < 0 || col >= matrix->size) {
printf("Error: Invalid row or column index.\n");
} else {
// 交換行和列的位置,確保 row <= col
if (row > col) {
int temp = row;
row = col;
col = temp;
}
int index = row * matrix->size + col - (row * (row + 1) / 2); // 計算壓縮存儲的索引
matrix->elements[index] = value;
}
}
// 獲取對稱矩陣中指定位置的元素值
int getElement(SymmetricMatrix *matrix, int row, int col) {
if (row < 0 || row >= matrix->size || col < 0 || col >= matrix->size) {
printf("Error: Invalid row or column index.\n");
return 0;
} else {
// 交換行和列的位置,確保 row <= col
if (row > col) {
int temp = row;
row = col;
col = temp;
}
int index = row * matrix->size + col - (row * (row + 1) / 2); // 計算壓縮存儲的索引
return matrix->elements[index];
}
}
// 打印對稱矩陣
void printMatrix(SymmetricMatrix *matrix) {
for (int i = 0; i < matrix->size; i++) {
for (int j = 0; j < matrix->size; j++) {
printf("%d ", getElement(matrix, i, j));
}
printf("\n");
}
}
int main() {
SymmetricMatrix matrix;
int size = 4; // 假設(shè)對稱矩陣的維度為3
initialize(&matrix, size);
// 設(shè)置對稱矩陣的元素值
setElement(&matrix, 0, 0, 1);
setElement(&matrix, 1, 1, 2);
setElement(&matrix, 2, 2, 3);
setElement(&matrix, 1, 0, 4);
setElement(&matrix, 2, 0, 5);
setElement(&matrix, 2, 1, 6);
// 打印對稱矩陣
printMatrix(&matrix);
return 0;
}
到了這里,關(guān)于【數(shù)據(jù)結(jié)構(gòu)】數(shù)組和字符串(三):特殊矩陣的壓縮存儲:三角矩陣、對稱矩陣——一維數(shù)組的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!