数据结构-稀疏矩阵

来源:互联网 发布:淘宝违反数量限制规则 编辑:程序博客网 时间:2024/05/19 17:51

稀疏矩阵:矩阵中有效数据的个数远远小于无效数据的个数,则可以称之为稀疏矩阵


如果还像以前那样将每个稀疏矩阵的数据都存储起来,则会造成内存的很大程度的浪费,所以应用特别的存储方式。

稀疏矩阵的压缩存储:

使用{row,col,value}三元组存储每一个有效数据,三元组按原矩阵中的位置,以行优先级先后顺序依次存放。


矩阵的转置:将矩阵上行列互换,原来的A[i][j]就等于现在的A[j][i] .


矩阵的快速转置:                                 

建立rowCounts和rowStart, 统计每列的个数和每列起始位置,第i行的起始位置等于上一行的起始位置加上上一行的个数。



#pragma once#include<vector>//稀疏矩阵template<class T>struct Triple{T _value;//值size_t _row;//行size_t _col;//列Triple(const T& value = T(), size_t row = 0, size_t col = 0):_value(value), _row(row), _col(col){}};template <class T>class SparseMatrix{public:SparseMatrix()//无参:_rowSize(0), _colSize(0){}//a为数组   m行  n列  invalid为非法值SparseMatrix(T*a, size_t m, size_t n, const T& invalid):_rowSize(m), _colSize(n), _invalid(invalid){for (size_t i = 0; i < m; i++){for (size_t j = 0; j < n; j++){if (a[i*n + j] != invalid)//不等于非法值{Triple<T> tmp(a[i*n + j], i, j);//构造一个tmp_a.push_back(tmp);//放入vector中}}}}void Print(){int index = 0;for (int i = 0; i < _rowSize; i++){for (int j = 0; j < _colSize; j++){if ((index < _a.size()) &&(_a[index]._row == i) &&(_a[index]._col == j)){cout << _a[index]._value << " ";index++;}else{cout << _invalid << " ";}}cout << endl;}cout << endl;}SparseMatrix<T> Transport(){SparseMatrix<T> tmp;tmp._colSize = _rowSize;tmp._rowSize = _colSize;tmp._invalid = _invalid;for (size_t i = 0; i < _colSize; i++){size_t index = 0;while (index < _a.size()){if (_a[index]._col == i){Triple<T> t;t._value = _a[index]._value;t._row = _a[index]._col;//行列互换t._col = _a[index]._row;//行列互换tmp._a.push_back(t);//压入tmp}++index;}}return tmp;}//快速转置的思想:建立rowCounts和rowStart, 统计每列的个数和每列起始位置,//第i行的起始位置等于上一行的起始位置加上上一行的个数。SparseMatrix<T> FastTransport(){SparseMatrix<T> result;//行列size互换result._rowSize = _colSize;result._colSize = _rowSize;result._invalid = _invalid;//建立rowCounts和rowStartint* rowCounts = new int[_colSize];int* rowStart = new int[_colSize];memset(rowCounts, 0, sizeof(int)*_colSize);memset(rowStart, 0, sizeof(int)*_colSize);result._a.resize(_a.size());//开辟与_a相同的空间,并初始化为0for (size_t i = 0; i < _colSize; i++){rowCounts[_a[i]._col]++;}rowStart[0] = 0;for (size_t i = 1; i < _colSize; i++){rowStart[i] = rowCounts[i - 1] + rowStart[i - 1];}//快速转置size_t index = 0;Triple<T> tmp;while (index < _a.size()){int row = _a[index]._col;//行数int rowIndex = rowStart[row];//当前行的起始位置//交换行和列tmp._value = _a[index]._value;tmp._row = _a[index]._col;tmp._col = _a[index]._row;result._a[rowIndex] = tmp;rowStart[row]++;index++;}return result;}protected:/*Triple<T>* _a;size_t size;*/vector<Triple<T>> _a;size_t _rowSize;   //行size_t _colSize;  //列T _invalid;  //非法值};void Test(){int array[6][5] ={{ 1, 0, 3, 0, 5 },{ 0, 0, 0, 0, 0 },{ 0, 0, 0, 0, 0 },{ 2, 0, 4, 0, 6 },{ 0, 0, 0, 0, 0 },{ 0, 0, 0, 0, 0 },};SparseMatrix<int> sm1((int*)array, 6, 5, 0);sm1.Print();SparseMatrix<int> sm2 = sm1.Transport();sm2.Print();SparseMatrix<int> sm3 = sm1.FastTransport();sm3.Print();}


如有不正确的地方,希望能够指出,一起学习进步,O(∩_∩)O谢谢了。

1 0
原创粉丝点击