在矩阵中,若数值为0的元素数目远远多于非0元素的数目,并且非0元素分布没有规律时,则称该矩阵为稀疏矩阵;与之相反,若非0元素数目占大多数时,则称该矩阵为稠密矩阵。定义非零元素的总数比上矩阵所有元素的总数为矩阵的稠密度。
二、图解和代码实现 2.1 结构图由上图可知非零元素远少于零元素,这是稀疏矩阵最大的特点
2.2 代码实现Triple.cpp
#include#include template class Triple //三元组表 { private: struct Node //三元组表的类型,一个struct类型代表一个结点 { int row; //非零元素的行号 int col; //非零元素的列号 Type data; //非零元素的值 Node(int r = -1, int c = -1, Type d = 0) //结点构造函数 { row = r; col = c; data = d; } void pushNodeValue(int r, int c, Type d) //元素赋值 { row = r; col = c; data = d; } }; Node *matrix; //三元组表 int numRow; //矩阵的行数 int numCol; //矩阵的列数 int count; //非零元素个数 int maxSize; //矩阵容量 public: Triple(int r, int c, int size = 10); //构造函数,默认矩阵容量为10 ~Triple() { delete[] matrix; } //析构函数 void pushValue(int r, int c, const Type &size); //元素赋值 Type getValue(int r, int c) const; //取元素的值 void transpose(const Triple &t); //用当前对象保存A的转置的三元组表 void print() const; //输出三元组表 void resize(); //扩大三元组表空间 }; template Triple ::Triple(int r, int c, int size) //行数r,列数c,非零个数size { assert(r >= 0 && c >= 0 && size >= 0); //判定传入的数是否越界 numRow = r; numCol = c; count = 0; if (r * c > size) // r*c为最大容量 { maxSize = size; } else { maxSize = r * c; //最多只能有c*r个非零元素 } if (maxSize != 0) { matrix = new Node[maxSize]; //开辟矩阵空间 } else { matrix = nullptr; } } template void Triple ::pushValue(int r, int c, const Type &size) //元素赋值 { if (size == 0) // 0不存储 { return; } assert(r >= 0 && r < numRow && c >= 0 && c < numCol); //越界报错 if (count == maxSize) //空间满扩容 { resize(); } int i; for (i = 0; i < count; i++) { if (matrix[i].row > r || (matrix[i].row == r && matrix[i].col > c)) { break; //说明要插入的位置没有元素,跳出循环 } if (matrix[i].row == r && matrix[i].col == c) { //说明要插入位置已有元素,则用新值覆盖它 matrix[i].pushNodeValue(r, c, size); return; } } for (int j = count - 1; j >= i; j--) { matrix[j + 1] = matrix[j]; } matrix[i].pushNodeValue(r, c, size); count++; } template Type Triple ::getValue(int r, int c) const //取元素的值 { if (count == 0) //如果为空,直接返回0 { return 0; } assert(r >= 0 && r < numRow && c >= 0 && c < numCol); //越界报错 for (int i = 0; i < count; i++) { if (matrix[i].row == r && matrix[i].col == c) { return matrix[i].data; } } return 0; } // a为未逆置前,b是逆置后,根据矩阵的规律发现,逆置后:a[i][j]=b[j][i] template void Triple ::transpose(const Triple &A) //用当前对象保存A的转置的三元组表 { //先构建b矩阵 numCol = A.numRow; numRow = A.numCol; if (maxSize < A.count) //如果b矩阵存不下a的逆置,重新开辟空间 { maxSize = A.maxSize; delete[] matrix; //释放b的空间 matrix = new Node[maxSize]; } count = A.count; int q = 0; //控制当前对象matrix空间的下标 for (int i = 0; i < A.numCol; i++) //按列转序,列号不为-1则存在非0元素 { for (int j = 0; j < A.count; j++) // j控制对象A的数组的下标 { if (A.matrix[j].col == i) { matrix[q].row = A.matrix[j].col; matrix[q].col = A.matrix[j].row; matrix[q].data = A.matrix[j].data; q++; } } } } template void Triple ::print() const //输出三元组表 { std::cout << "Row:" << numRow << "t" << "Col:" << numCol << "t" << "Count:" << count << std::endl; for (int i = 0; i < count; i++) { std::cout << "(" << matrix[i].row << "," << matrix[i].col << "," << matrix[i].data << ")" << std::endl; } } template void Triple ::resize() //扩大三元组表空间 { Node *tmp = matrix; //把原空间先给tmp保管 if (2 * maxSize > numRow * numCol) { maxSize = numRow * numCol; } else { maxSize = 2 * maxSize; } matrix = new Node[maxSize]; //创建新空间 for (int i = 0; i < count; i++) //把数据放入新空间中 { matrix[i] = tmp[i]; } delete[] tmp; tmp = nullptr; }
main.cpp
#include#include "triple.h" using namespace std; void test01() { Triple T1(3, 3, 2); T1.pushValue(0, 2, 3); T1.pushValue(0, 1, 2); T1.pushValue(0, 0, 1); T1.print(); //取位置为(2,0),(0,2)的元素 int value01 = T1.getValue(2, 0); int value02 = T1.getValue(0, 2); cout << "value01 = " << value01 << "t" << "value02 = " << value02 << endl; //逆置 Triple T2(3, 3, 2); T2.transpose(T1); T2.print(); } int main() { test01(); return 0; }



