稀疏矩阵的实现(三元组存储)C++
2015-11-17 15:33
621 查看
通过三元组存储稀疏矩阵,压缩存储空间
测试结果
/* 稀疏矩阵的实现 */ #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; }
测试结果
相关文章推荐
- C#调用C++编写的dll
- 了解指针,分分钟的事情 C++筆記--指針
- 【c++】双向链表容器list
- 十字链表的实现C++
- C++面试问题汇总
- 二叉树的基本操作C++
- c++ swap 函数
- 【C++】广义表
- VC++ 动态检测串口的热插拔
- C++经典开源库
- C#调用C++动态库时类型转换
- C++中,结构体vector使用sort排序
- C++文件读写详解(ofstream,ifstream,fstream)
- 【C++】返回栈中最小的元素,要求时间复杂度为O(1)
- 左旋字符
- LeetCode(31): Next Permutation (C++)
- QString与char *型转换
- 【C++】稀疏矩阵的普通转置与快速转置
- c++为什么将宏改进为内联、const
- 【C++】迷宫