三元组压缩存储稀疏矩阵的C++类模板实现
2017-03-25 17:12
501 查看
一 简介
设m*n 矩阵中有t 个非零元素且t<<m*n,这样的矩阵称为稀疏矩阵。
遇到阶数很高的大型稀疏矩阵,按常规分配方法,顺序分配在计算机内,占用内存过大。
故有另一种存储方法,仅仅存放非零元素。
但对于这类矩阵,通常零元素分布没有规律,为能找到相应的元素,仅存储非零元素是不够的,还要记下它所在的行和列。
将三元组按行优先的顺序,同一行中列号从小到大的规律排列成一个线性表,称为三元组表,采用顺序存储方法存储该表。一张图举例说明问题:
二 编程实现
准备的测试文件有:
1. 先建立一个CPMatrix.h
2. 当然习惯了C.h包含各种有用没用的头文件(可多不可少)
3. 最后是测试
运行结果:
设m*n 矩阵中有t 个非零元素且t<<m*n,这样的矩阵称为稀疏矩阵。
遇到阶数很高的大型稀疏矩阵,按常规分配方法,顺序分配在计算机内,占用内存过大。
故有另一种存储方法,仅仅存放非零元素。
但对于这类矩阵,通常零元素分布没有规律,为能找到相应的元素,仅存储非零元素是不够的,还要记下它所在的行和列。
将三元组按行优先的顺序,同一行中列号从小到大的规律排列成一个线性表,称为三元组表,采用顺序存储方法存储该表。一张图举例说明问题:
二 编程实现
准备的测试文件有:
1. 先建立一个CPMatrix.h
#ifndef CPMatrix_H #define CPMatrix_H enum Sub_Or_Add{ Sub,Add//在下面成员函数选择加法或减法的标志 }; template <typename T> struct Triple{//三元组类型结构体 int i,j;//行列下标 T e;//非零元素的值 }; const int MAX_SIZE=100;//非零元素的个数最大值 const int MAX_RC=20;//矩阵最大行数 template <typename T> class CPMatrix{ private: Triple<T> data[MAX_SIZE+1];//非零元三元组表,data[0]不用 int rpos[MAX_RC+1];//各行第一个非零值的位置表 int row,col,num;//行列数,非零元个数 public: CPMatrix(){ row=col=num=1; } CPMatrix(char * FileName){ CreateSMatrixFromFile(FileName); } bool CreateSMatrixFromFile(char *FileName="test1.txt"){ int i,j; ifstream fin(FileName); fin>>row>>col>>num; if(num>MAX_SIZE||row>MAX_RC) return false; data[0].i=0; for(i=1;i<=num;i++){ fin>>data[i].i>>data[i].j>>data[i].e; if(data[i].i<1||data[i].i>row||data[i].j<1 ||data[i].j>col) return false; if(data[i].i<data[i-1].i||data[i].i==data[i-1].i &&data[i].j<data[i-1].j)//行或者列输入顺序错误!! return false; } fin.close(); for(i=1;i<=row;i++){ rpos[i]=1;//先初始化:每一行第一个非零值元素都挤在三元组第一个位置data[1],显然不可能 } for(i=1;i<=num;i++) for(j=data[i].i+1;j<=row;j++)//从非零元素所在行的下一行开始 rpos[j]++;//相当于每行第一个非零元素的位置后移一位 return true; } void CopySMatrix(const CPMatrix<T> &M){ int i; row=M.row; col=M.col; num=M.num; for(i=0;i<=M.num;i++) data[i]=M.data[i]; for(i=0;i<M.row;i++) rpos[i]=M.rpos[i]; } void TransposeSMatrix(const CPMatrix<T> &M){ int i,j,k,colm[MAX_RC+1];//[0]不用!! row=M.col; col=M.row; num=M.num; if(num){//矩阵非空 for(i=1;i<=row;++i)//从矩阵第一列到最后一列 colm[i]=0; for(i=1;i<=num;++i) ++colm[M.data[i].j];//统计每一列有多少个元素,最后colm =m表示第n列有m个非零元素 rpos[1]=1; for(i=2;i<=row;++i) rpos[i]=rpos[i-1]+colm[i-1];//最后rpos[i]=a表示M转置后第i行第一个非零元素的位置data[a] for(i=1;i<=row;++i) colm[i]=rpos[i];//此时colm[]存放每一行第一个非零元素在M转置后应该存放的位置data[] for(i=1;i<=num;++i){//对于每一个非零元素 j=M.data[i].j;//取得行号 k=colm[j]++;//k代表该行第n个非零元素的位置,colm[]自增准备下次该行后一个非零元素的读取 data[k].i=j;//开始对调 data[k].j=M.data[i].i; data[k].e=M.data[i].e; } } } bool Sub_Add_SMatrix(const CPMatrix<T> &M,const CPMatrix<T> &N,Sub_Or_Add mod){ int p,q,up,uq; if(M.row!=N.row||M.col!=N.col) return false; row=M.row; col=M.col; num=0; for(int k=1;num<=MAX_SIZE&&k<=M.row;++k)//k指示行号 { rpos[k]=num+1;//“和矩阵”的第K行的第一个元素的位置data[] p=M.rpos[k];//p指示M第K行当前元素的位置 q=N.rpos[k]; if(k<M.row){//不是最后一行 up=M.rpos[k+1];//下一行的第一个元素位置data 的n是本行元素的上界最大 uq=N.rpos[k+1]; } else{ up=M.num+1;//最后一行也设置上届 uq=N.num+1; } while(p<up&&q<uq) if(M.data[p].j<N.data[q].j){//M当前元素的列 < N当前元素的列 data[++num] = M.data[p++];//不论加法减法都是把M赋给“和矩阵” } else if(M.data[p].j>N.data[q].j){//M当前元素的列 > N当前元素的列,就是N在前面 data[++num]=N.data[q++];//加法直接赋值 if(mod==Sub) data[num].e *= (-1);//减法还要乘-1,应为相当于用0减去!!! } else{ if(M.data[p].e-N.data[q].e!=0&&mod==Sub){ data[++num]=M.data[p]; data[num].e-=N.data[q].e; } if(M.data[p].e+N.data[q].e!=0&&mod==Add){ data[++num]=M.data[p]; data[num].e+=N.data[q].e; } p++; q++; } while(p<M.rpos[k+1]&&p<=M.num) data[++num]=M.data[p++]; while(q<N.rpos[k+1]&&q<=N.num){ data[++num] = N.data[q++]; if(mod==Sub) data[num].e *= (-1); } } if(num>MAX_SIZE) return false; else return true; } bool MultSMatrix(const CPMatrix<T> &M,CPMatrix<T> &N){ int i,j,q,p,up,uq; T temp;//暂时存放data[].e CPMatrix<T> E;//存放N转置矩阵 if(M.col!=N.row) return false; row=M.row; col=N.col; num=0; E.TransposeSMatrix(N); for(i=1;i<=row;i++)//对于乘积每一行 for(j=1;j<=col;j++){//对于乘积每一列 temp=0; p=M.rpos[i];//p指示M在第i行的第一个非零元素位置 q=E.rpos[j];//q指示E在第j行(也就是N在第j列)的第一个非零元素位置 if(i<M.row) up=M.rpos[i+1]; else up=M.num+1; if(j<E.row) uq=E.rpos[j+1]; else uq=E.num+1; while(p<up&&q<uq) if(M.data[p].j<E.data[q].j) p++; else if(M.data[p].j>E.data[q].j) q++; else temp+=M.data[p++].e*E.data[q++].e; if(temp){ if(++num>MAX_SIZE) return false; data[num].i=i; data[num].j=j; data[num].e=temp; } } return true; } void PrintSMatrix()const{ int k=1; const Triple<T> *p=data+1;//p指向第一个非零元素 if(num==0) return ; for(int i=1;i<=row;i++){ for(int j=1;j<=col;j++){ if(k<=num&&p->i==i&&p->j==j){ cout<<setw(3)<<(p++)->e; k++; } else cout<<setw(3)<<0; } cout<<endl; } } }; #endif
2. 当然习惯了C.h包含各种有用没用的头文件(可多不可少)
//C.h 几乎各程序都需要用到的文件包含宏命令和使用名空间 #ifndef C_H #define C_H #include <iostream> #include <fstream> #include <iomanip> #include <cmath> #include <string> #include <vector> #include <list> #include <stack> #include <queue> #include <bitset> #include <algorithm> #include <ctime> #include <cstdarg> #include <assert.h> using namespace std; #endif
3. 最后是测试
#include "C.h" #include "CPMatrix.h" int main() { bool f; CPMatrix<int> A("test2.txt"), B, C,D; cout<<"test2.txt建矩阵A="<<endl; A.PrintSMatrix(); f=B.CreateSMatrixFromFile(); if(f) { cout<<"默认test1.txt建矩阵B="<<e a157 ndl; B.PrintSMatrix(); } C.CopySMatrix(A); cout<<"A的拷贝C="<<endl; C.PrintSMatrix(); f=C.CreateSMatrixFromFile("test3.txt"); if(f) { cout<<"由test3.txt重建C="<<endl; C.PrintSMatrix(); } f=B.Sub_Add_SMatrix(A, C,Add); if(f) { cout<<"B=A+C="<<endl; B.PrintSMatrix(); } f=D.Sub_Add_SMatrix(B, A,Sub); if(f) { cout<<"D=B-A="<<endl; D.PrintSMatrix(); } A.TransposeSMatrix(C); cout<<"C的转置重建A:"<<endl; A.PrintSMatrix(); f=B.MultSMatrix(C, A); if(f) { cout<<"B=C×A="<<endl; B.PrintSMatrix(); } return 0; }
运行结果:
相关文章推荐
- 三元组实现稀疏矩阵的压缩存储与转置 (Sparse matrix compression storage and transposition base on triple)
- 三元组表压缩存储稀疏矩阵实现稀疏矩阵的快速转置(Java语言描述)
- 稀疏矩阵三元组方式压缩存储 c++模板类实现
- 三元组表压缩存储稀疏矩阵实现稀疏矩阵的快速转置(Java语言描述)
- 稀疏矩阵的压缩存储与快速转置 三元组法 类与对象实现
- C++实现稀疏矩阵的压缩存储、转置、快速转置
- 利用稀疏矩阵的“三元组表”存储结构,实现两个矩阵的相加。
- 稀疏矩阵的压缩存储及转置,快速转置法,C++代码实现
- 数组与广义表_稀疏矩阵的压缩存储_三元组做存储结构_矩阵转置
- C++实现稀疏矩阵的压缩存储实例
- 数据结构编程笔记十三:第五章 数组和广义表 稀疏矩阵的压缩存储实现
- C++ 实现稀疏矩阵的压缩存储的实例
- 矩阵的压缩存储(稀疏矩阵的十字链表存储、稀疏矩阵的三元组行逻辑链接的顺序表存储表示、稀疏矩阵的三元组顺序表存储表示)
- 数组与广义表_稀疏矩阵的压缩存储_三元组做存储结构_矩阵相乘
- 稀疏矩阵--三元组表来压缩存储及转置
- 稀疏矩阵的实现(三元组存储)C++
- 稀疏矩阵的三元组表示的实现及应用(2)——采用三元组存储稀疏矩阵,设计两个稀疏矩阵相加的运算算法
- 矩阵的压缩存储————用三元组表存储稀疏矩阵
- 用三元组存储稀疏矩阵并实现转置
- 稀疏矩阵三元组存储 c实现