稀疏矩陣的實現(三元組儲存)C++
阿新 • • 發佈:2019-02-10
通過三元組儲存稀疏矩陣,壓縮儲存空間
測試結果/* 稀疏矩陣的實現 */ #include<iostream> #include<fstream> #include<string> using namespace std; //儲存域 const int MAX_N = 100; class elem_node { public: int elem_row;//元素行號 int elem_col;//元素列號 int elem_value;//元素值 }; class Node { public: int total_row;//總行數 int total_col;//總列數 int total_num;//非0元素總數 elem_node data[MAX_N];//非0元素陣列 }; class Matrix { public: Matrix(){} ~Matrix(){} //構建稀疏矩陣三元組 void CreateMat(string filename, int rows, int cols) { int i, j; int fdata; ifstream readFile; mat.total_num = 0; mat.total_col = cols;//總行數 mat.total_row = rows;//總列數 readFile.open(filename); //開啟錯誤 if (readFile.bad() || readFile.fail()) { exit(0); } //檔案正常開啟 if (readFile.is_open()) { for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { readFile >> fdata; if (readFile.good() && fdata != 0) { mat.data[mat.total_num].elem_row = i;//元素行號 mat.data[mat.total_num].elem_col = j;//元素列號 mat.data[mat.total_num].elem_value = fdata;//元素之 mat.total_num++;//儲存陣列下標+1 } } } } readFile.close(); } //指定位置賦值,若不存在,則插入 bool Value(int elem, int i, int j) { if (i >= mat.total_row || j >= mat.total_col) { return false; } else { int k = 0, k1; //搜尋行號<3,5> <3,6> <3,7> <3,8> 查詢<3,6> while (k<mat.total_num&&i>mat.data[k].elem_row) { k++; } //行號相等時,搜尋列號 while (k<mat.total_num&&i == mat.data[k].elem_row&&j>mat.data[k].elem_col) { k++; } //退出時行號和列號相等於給定值 if (mat.data[k].elem_row == i&&mat.data[k].elem_col == j) { mat.data[k].elem_value = elem; } //退出時行號列號不都等於給定值 else { //三元組中位於該位置後的元素都後移 for (k1 = mat.total_num - 1; k1 >= k; k1--) { mat.data[k1 + 1].elem_row = mat.data[k1].elem_row; mat.data[k1 + 1].elem_col = mat.data[k1].elem_col; mat.data[k1 + 1].elem_value = mat.data[k1].elem_value; } //插入值 mat.data[k].elem_row = i; mat.data[k].elem_col = j; mat.data[k].elem_value = elem; mat.total_num++; } } return true; } //查詢並輸出值 bool Assign(int &res, int i, int j) { if (i > mat.total_row || j > mat.total_col) { res = 0; return false; } else { int k = 0; //查詢行 while (k<mat.total_num&&i>mat.data[k].elem_row) { k++; } //行數匹配,查詢列 while (k<mat.total_num&&i == mat.data[k].elem_row&&j>mat.data[k].elem_col) { k++; } //找到 if (i == mat.data[k].elem_row&&j == mat.data[k].elem_col) { res = mat.data[k].elem_value; return true; } //否則 else { res = 0; return false; } } } //輸出三元組 void DispMat() { if (mat.total_num <= 0) { return; } else { int i; for (i = 0; i < mat.total_num; i++) { cout << "<" << mat.data[i].elem_row << "," << mat.data[i].elem_col << "," << mat.data[i].elem_value << ">" << endl; } } } //輸出三元組 void DispMat(Node mat) { if (mat.total_num <= 0) { return; } else { int i; for (i = 0; i < mat.total_num; i++) { cout << "<" << mat.data[i].elem_row << "," << mat.data[i].elem_col << "," << mat.data[i].elem_value << ">" << endl; } } } //轉置矩陣 Node TranMat() { Node tranMat; tranMat.total_col = 0; tranMat.total_row = 0; tranMat.total_num = 0; if (mat.total_num <= 0) { return tranMat; } else { int p = 0, i, c; tranMat.total_col = mat.total_col; tranMat.total_row = mat.total_row; tranMat.total_num = mat.total_num; for (i = 0; i < mat.total_row; i++)//遍歷所有行 { for (c = 0; c < mat.total_num; c++)//對於行,遍歷所有三元組元素 { if (i == mat.data[c].elem_row)//若三元組中存在行號與i相等的組,則轉置 { tranMat.data[p].elem_row = mat.data[c].elem_col; tranMat.data[p].elem_col = mat.data[c].elem_row; tranMat.data[p].elem_value = mat.data[c].elem_value; p++; } } } return tranMat; } } //矩陣相加 Node MatAdd(Node mat1, Node mat2) { Node mat; //迴圈變數初始化 int i = 0, j = 0, k = 0; //三元組初始化 mat.total_col = 0; mat.total_num = 0; mat.total_row = 0; //矩陣不可相加 if (mat1.total_col != mat2.total_col || mat1.total_row != mat2.total_row) { return mat; } //課相加 else { //總行列數賦值 mat.total_row = mat1.total_row; mat.total_col = mat1.total_col; //遍歷三元組 while (i < mat1.total_num&&j < mat2.total_num) { //兩個三元組中對應元素行座標相等 if (mat1.data[i].elem_row == mat2.data[j].elem_row) { //對應列座標mat1小 if (mat1.data[i].elem_col < mat2.data[j].elem_col) { //賦值 mat.data[k].elem_row = mat1.data[i].elem_row; mat.data[k].elem_col = mat1.data[k].elem_col; mat.data[k].elem_value = mat1.data[i].elem_value; k++; i++; } //對應列座標mat1大 else if (mat1.data[i].elem_col>mat2.data[j].elem_col) { //賦值 mat.data[k].elem_row = mat2.data[j].elem_row; mat.data[k].elem_col = mat2.data[j].elem_col; mat.data[k].elem_value = mat2.data[k].elem_value; k++; j++; } //對應列座標也相等 else { //求對應元素和 int temp_value = mat1.data[i].elem_value + mat2.data[j].elem_value; //若和值不等於0則賦值 if (temp_value != 0) { mat.data[k].elem_row = mat1.data[i].elem_row; mat.data[k].elem_col = mat1.data[i].elem_col; mat.data[k].elem_value = temp_value; k++; } i++; j++; } } //對應行座標mat1小 else if (mat1.data[i].elem_row < mat2.data[j].elem_row) { //賦值 mat.data[k].elem_row = mat1.data[i].elem_row; mat.data[k].elem_col = mat1.data[i].elem_col; mat.data[k].elem_value = mat1.data[i].elem_value; k++; j++; } //對應行座標mat1大 else { //賦值 mat.data[k].elem_row = mat2.data[j].elem_row; mat.data[k].elem_col = mat2.data[j].elem_col; mat.data[k].elem_value = mat2.data[j].elem_value; k++; j++; } } //總元素個數 mat.total_num = k; return mat; } } //獲取矩陣首地址 Node &get_address() { return mat; } private: Node mat; }; //三元組操作 class operation { public: operation() { m_mat.CreateMat("data",6,7); } ~operation(){} //輸出 void display() { cout << "Output" << endl; m_mat.DispMat(); } //矩陣轉置 void trange() { cout << "Change" << endl; m_mat.DispMat(m_mat.TranMat()); } //查詢 void is_fond() { cout << "Fond Value" << endl; int res; m_mat.Assign(res, 2, 0); cout << res << endl; } //賦值 void give_value() { cout << "Give New Value" << endl; m_mat.Value(18, 3, 4); m_mat.DispMat(); } //矩陣相加 void MatAdd() { cout << "Matrix Add" << endl; Matrix m_mat2; m_mat2.CreateMat("data1", 6, 7); m_mat.DispMat(m_mat.MatAdd(m_mat.get_address(), m_mat2.get_address())); } private: Matrix m_mat; }; int main() { operation m_opr; m_opr.display();//輸出 m_opr.give_value();//賦值 m_opr.is_fond();//查詢 m_opr.trange();//轉置 m_opr.MatAdd(); return 0; }