//CrossList.h #ifndef CROSSLIST_H #define CROSSLIST_H #include<iostream> using namespace std; class Node { public: Node(int i_val=0,int j_val=0,int e_val=0):i(i_val),j(j_val),e(e_val) { right=NULL; down=NULL; } ~Node() { right=NULL; down=NULL; } int i; //非零元行坐标 int j; //非零元列坐标 int e; //非零元值 Node* right; //非零元所在行后继非零元 Node* down; //非零元所在列后继非零元 }; class CrossList //十字链表表示稀疏矩阵 { public: CrossList(int i=0,int j=0):rhead(NULL),chead(NULL),m(i),n(j),t(0) { InitMatrix(); } CrossList(const CrossList& rhs); //复制构造函数 ~CrossList() { DestoryMatrix(); } CrossList operator+(const CrossList& rhs); //重载加法操作符 CrossList operator*(const CrossList& rhs); //重载乘法操作符 CrossList Transpose(); //求转置矩阵 friend ostream& operator<<(ostream& os,const CrossList& rhs); //重载输出操作符 Node** rhead; //行基址 Node** chead; //列基址 bool InsertNode(int i,int j,int e); //在i行j列插入值为e的结点 int get_t() { return t; } private: void InitMatrix(); //初始化稀疏矩阵 void DestoryMatrix(); //销毁稀疏矩阵 int GetVal(int i,int j) const; //返回i行j列的结点值 int m; //稀疏矩阵的行数 int n; //稀疏矩阵的列数 int t; //稀疏矩阵的非零元个数 }; #endif //CrossList.cpp #include <iostream> #include "CrossList.h" using namespace std; CrossList::CrossList(const CrossList& rhs) { m=rhs.m; n=rhs.n; t=0; InitMatrix(); for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) if(rhs.GetVal(i,j)) InsertNode(i,j,rhs.GetVal(i,j)); //非零元才插入 } CrossList CrossList::operator+(const CrossList& rhs) { if(m!=rhs.m || n!=rhs.n) { CrossList c; c.InitMatrix(); return c; } CrossList c(m,n); c.InitMatrix(); for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) { if(GetVal(i,j) && !rhs.GetVal(i,j)) // 左操作数不为0,右操作数为0 { c.InsertNode(i,j,GetVal(i,j)); } else if(!GetVal(i,j) && rhs.GetVal(i,j)) // 左操作数为0,右操作数不为0 { c.InsertNode(i,j,rhs.GetVal(i,j)); } else if(GetVal(i,j) && rhs.GetVal(i,j)) // 左右操作数都不为0 { if((GetVal(i,j)+rhs.GetVal(i,j))!=0) // 左右操作数和不为0 { c.InsertNode(i,j,GetVal(i,j)+rhs.GetVal(i,j)); } } } return c; } CrossList CrossList::operator*(const CrossList& rhs) { if(n!=rhs.m) // 左操作数的行不等于右操作数的列则失败 { CrossList c; c.InitMatrix(); return c; } CrossList c(m,rhs.n); c.InitMatrix(); int sum=0; for(int i=1;i<=m;i++) // 控制左操作数的行 for(int j=1;j<=rhs.n;j++) // 控制右操作数的列 { sum=0; for(int k=1;k<=n;k++) // 控制元素相乘 { sum+=GetVal(i,k)*rhs.GetVal(k,j); } if(sum) c.InsertNode(i,j,sum); } return c; } CrossList CrossList::Transpose() { CrossList c(n,m); //转换为n行m列 c.InitMatrix(); for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) if(GetVal(i,j)) //非零元才转换 { c.InsertNode(j,i,GetVal(i,j)); } return c; } void CrossList::InitMatrix() { rhead=new Node*[m]; //行基址指针rhead指向m行行指针 chead=new Node*[n]; //列基址指针chead指向n列列指针 for(int i=0;i<m;i++) { rhead[i]=new Node(); } for(int j=0;j<n;j++) { chead[j]=new Node(); } } void CrossList::DestoryMatrix() { for(int i=0;i<n;i++) { delete chead[i]; //删除控制列的指针 } for(int j=0;j<m;j++) //删除控制行的指针 { Node* p=rhead[j]; Node* del_p=NULL; while(p->right) { del_p=p; //del_p指向即将被删除的结点 p=p->right; //p指向下一个将被结点 delete del_p; } } } bool CrossList::InsertNode(int i,int j,int e) { if( e==0 || i<1 || i>m || j<1 || j>n ) //插入位置或值不合法,返回false return false; Node* pRow=rhead[i-1]; Node* pCol=chead[j-1]; Node* pNew=new Node(i,j,e); if(!pRow->right && !pCol->down) //插入元素所在行和列均为空的情况 { pRow->right=pNew; pCol->down=pNew; t++; return true; } if(!pRow->right && pCol->down) //插入元素所在行为空,列不为空的情况 { while( pCol->down&& (pCol->down->i < i)) { pCol=pCol->down; } pNew->down=pCol->down; pCol->down=pNew; pRow->right=pNew; t++; return true; } if(!pCol->down && pRow->right) //插入元素所在列为空,行不为空的情况 { while( pRow->right&& (pRow->right->j < j)) { pRow=pRow->right; } pNew->right=pRow->right; pRow->right=pNew; pCol->down=pNew; t++; return true; } if(pRow->right && pCol->down) //插入元素所在行和列都不为空 { while( pRow->right&& (pRow->right->j < j)) { pRow=pRow->right; } while( pCol->down&& (pCol->down->i < i)) { pCol=pCol->down; } pNew->right=pRow->right; pNew->down=pCol->down; pRow->right=pNew; pCol->down=pNew; t++; return true; } return false; } int CrossList::GetVal(int i,int j) const { Node* p=rhead[i-1]; //定位行 if(p->right) { while(p) { if(p->j==j) //行列都相等则返回该项数据元素 return p->e; p=p->right; //否则比较下一列 } } return 0; } ostream& operator<<(ostream& os,const CrossList& rhs) { for(int i=1;i<=rhs.m;i++) { for(int j=1;j<=rhs.n;j++) if(rhs.GetVal(i,j)) cout<<rhs.GetVal(i,j)<<" "; else cout<<0<<" "; cout<<"/n"; } return os; } //Matrix.cpp #include <iostream> #include "CrossList.h" using namespace std; int main() { CrossList c1(2,4); c1.InsertNode(1,1,1); c1.InsertNode(1,2,3); c1.InsertNode(1,3,3); c1.InsertNode(1,4,-1); c1.InsertNode(2,1,2); c1.InsertNode(2,2,1); c1.InsertNode(2,3,0); c1.InsertNode(2,4,2); cout<<"C1矩阵:/n"<<c1<<"非零元个数为:"<<c1.get_t()<<endl; CrossList c2(2,4); for(int i=1;i<=2;i++) for(int j=1;j<=4;j++) c2.InsertNode(i,j,i*j); cout<<"/nC2矩阵:/n"<<c2<<"非零元个数为:"<<c2.get_t()<<endl; CrossList c3(4,3); c3.InsertNode(1,1,4); c3.InsertNode(1,2,1); c3.InsertNode(1,3,0); c3.InsertNode(2,1,-1); c3.InsertNode(2,2,1); c3.InsertNode(2,3,3); c3.InsertNode(3,1,2); c3.InsertNode(3,2,0); c3.InsertNode(3,3,1); c3.InsertNode(4,1,1); c3.InsertNode(4,2,3); c3.InsertNode(4,3,4); cout<<"/nC2矩阵:/n"<<c3<<"非零元个数为:"<<c3.get_t()<<endl; CrossList c4=c1*c3; cout<<"/nC4=C1*C3矩阵:/n"<<c4<<"非零元个数为:"<<c4.get_t()<<endl; CrossList c5=c1+c2; cout<<"/nC5=C1+C2矩阵:/n"<<c5<<"非零元个数为:"<<c5.get_t()<<endl; CrossList c6=c5.Transpose(); cout<<"/nC6=C5的转置矩阵:/n"<<c6<<"非零元个数为:"<<c6.get_t()<<endl; return 0; }