数组
多维数组的保存方式
- 行主映射
- 列主映射
类Array1D
- C++数组的缺陷
(1)越界问题:不能自动检测出越界
(2)输出问题:不能直接cout
(3)不支持对数组进行算数操作 - Array1D
template<class T>
class Array1D{
friend ostream& operator<<(ostream&,const Array1D<T>&);
public:
Array1D(int size=0);
Array1D(const Array1D<T>& v); //拷贝构造函数
~Array1D(){delete[] element;}
T& operator[](int i) const; //重载下标操作符越界的问题
int Size() {return size;}
//运算符重载实现数组整体运算
Array1D<T>& operator=(const Array1D<T>& v);
Array1D<T> operator+() const; // unary +
Array1D<T> operator+(const Array1D<T>& v) const;
Array1D<T> operator-() const; // unary minus
Array1D<T> operator-(const Array1D<T>& v) const;
Array1D<T> operator*(const Array1D<T>& v) const;
Array1D<T>& operator+=(const T& x);
Array1D<T>& ReSize(int sz);
private:
int size;
T* element; //一维数组
}
template<class T>
Array1D<T>::Array1D(int sz){ //构造一个空的数组
if (sz < 0)
throw BadInitializers();
size = sz;
element = new T[sz];
}
template<class T>
Array1D<T>::Array1D(const Array1D<T>& v){ //拷贝构造函数
size = v.size;
element = new T[size]; //获取空间
for (int i = 0; i < size; i++) //依次拷贝数组元素
element[i] = v.element[i];
}
template<class T>
T& Array1D<T>::operator[](int i) const{ //赋予[]意义,可以像普通数组一样使用Array1D
if (i < 0 || i >= size) //检查是否越界
throw OutOfBounds();
return element[I]; //返回元素的引用
} //O(1)
template<class T>
Array1D<T>& Array1D<T>::operator=(const Array1D<T>& v){ //重载=
if (this != &v) { //不允许自身的复制
size = v.size;
delete [] element; //释放原有空间
element = new T[size]; //分配与v相同大小的内存空间
for (int i = 0; i < size; i++) //复制数据
element[i] = v.element[i];
}
return *this;
} //O(size)
template<class T>
Array1D<T> Array1D<T>::operator+(const Array1D<T>& v) const{
if (size != v.size) //检查是否可加
throw SizeMismatch();
Array1D<T> w(size); //创建新的数组来存储结果
for (int i = 0; i < size; i++) //每个元素对应相加
w.element[i] = element[i] + v.element[i];
return w;
} //O(size)
template<class T>
Array1D<T> Array1D<T>::operator-(const Array1D<T>& v) const{
if (size != v.size) //检查是否可减
throw SizeMismatch();
Array1D<T> w(size); //创建新的数组来存储结果
for (int i = 0; i < size; i++) //每个元素对应相减
w.element[i] = element[i] - v.element[i];
return w;
} //O(size)
template<class T>
Array1D<T> Array1D<T>::operator*(const Array1D<T>& v) const{
if (size != v.size)
throw SizeMismatch();
Array1D<T> w(size);
for (int i = 0; i < size; i++)
w.element[i] = element[i] * v.element[i];
return w;
} //O(size)
template<class T>
Array1D<T> Array1D<T>::operator-() const{ //将数组全部置负
Array1D<T> w(size);
for (int i = 0; i < size; i++)
w.element[i] = - element[i];
return w;
} //O(size)
template<class T>
Array1D<T>&Array1D<T>::operator+=(const T& x){ //重载+=
for (int i = 0; i < size; i++)
element[i] += x;
return *this;
} //O(size)
- Array2D
template<class T>
class Array2D {
friend ostream& operator<<
(ostream&, const Array2D<T>&);
public:
int Rows() const {return rows;}
int Columns() const {return cols;}
private:
int rows, cols; //二维数组的大小
Array1D<T> *row; //本质是一位数组的数组
};
template<class T>
Array2D<T>::Array2D(int r, int c){//构造一个空的二维数组
if (r < 0 || c < 0) //检查是否越界
throw BadInitializers();
if ((!r || !c) && (r || c)) //行和列数都不能为0
throw BadInitializers();
rows = r;
cols = c;
//二维数组是一位数组的数组
row = new Array1D<T> [r];
for (int i = 0; i < r; i++)
row[i].ReSize(c);
} //O(rows*cols)
template<class T>
Array2D<T>::Array2D(const Array2D<T>& m){ //拷贝构造函数
rows = m.rows;
cols = m.cols;
row = new Array1D<T> [rows];
for (int i = 0; i < rows; i++)
row[i] = m.row[I]; //调用一位数组的重载=
} //O(rows*cols)
template<class T>
Array1D<T>& Array2D<T>::operator[](int i) const{ //重载[]使Array2D可以像普通数组那样
if (i < 0 || i >= rows) //检查是否越界
throw OutOfBounds();
return row[i];
} //O(1)
template<class T>
Array2D<T> Array2D<T>::operator-(const Array2D<T>& m) const{
if (rows != m.rows || cols != m.cols)//检查是否可减
throw SizeMismatch();
Array2D<T> w(rows,cols); //创建新的二维数组来存储结果
for (int i = 0; i < rows; i++)
w.row[i] = row[i] - m.row[I]; //调用一位数组的-运算符
return w;
}
template<class T>
Array2D<T> Array2D<T>::operator*(const Array2D<T>& m) const{
if (cols != m.rows) //检查是否可乘,注意条件
throw SizeMismatch();
Array2D<T> w(rows, m.cols);
for (int i = 0; i < rows; i++)
for (int j = 0; j < m.cols; j++) {
T sum = (*this)[i][0] * m[0][j];
for (int k = 1; k < cols; k++)
sum += (*this)[i][k] * m[k][j];
w[i][j] = sum;
}
return w;
} //O(rows*cols*m.cols)
矩阵
template<class T>
class Matrix {
friend ostream& operator<<(ostream&, const Matrix<T>&);
public:
Matrix(int r = 0, int c = 0);
Matrix(const Matrix<T>& m); //拷贝构造函数
~Matrix() {delete [] element;}
int Rows() const {return rows;}
int Columns() const {return cols;}
T& operator()(int i, int j) const;
Matrix<T>& operator=(const Matrix<T>& m);
Matrix<T> operator+() const;
Matrix<T> operator+(const Matrix<T>& m) const;
Matrix<T> operator-() const;
Matrix<T> operator-(const Matrix<T>& m) const;
Matrix<T> operator*(const Matrix<T>& m) const;
Matrix<T>& operator+=(const T& x);
private:
int rows, cols; //矩阵的大小
T *element; //元素数组
};
template<class T>
Matrix<T>::Matrix(int r, int c){ //构造函数
if (r < 0 || c < 0) //是否合法
throw BadInitializers();
if ((!r || !c) && (r || c)) //不能为0
throw BadInitializers();
rows = r;
cols = c;
element = new T [r * c];
} //O(1)/O(rows*cols)
template<class T>
T& Matrix<T>::operator()(int i, int j) const{
if (i < 1 || i > rows || j < 1|| j > cols) //检查是否越界
throw OutOfBounds();
return element[(i - 1) * cols + j - 1]; //注意这里行和列从1开始编号
} //O(1)
template<class T>
Matrix<T> Matrix<T>::operator-(const Matrix<T>& m) const{
if (rows != m.rows || cols != m.cols) //检查是否越界
throw SizeMismatch();
Matrix<T> w(rows, cols); //创建新的矩阵来存储结果
for (int i = 0; i < rows * cols; i++) //对应元素相减
w.element[i] = element[i] - m.element[i];
return w;
}
template<class T>
Matrix<T> Matrix<T>::operator*(const Matrix<T>& m) const{
if (cols != m.rows) //检查是否越界
throw SizeMismatch();
Matrix<T> w(rows, m.cols); //创建新的矩阵来存储结果
int ct = 0, cm = 0, cw = 0;
for (int i = 1; i <= rows; i++) {
for (int j = 1; j <= m.cols; j++) {
T sum = element[ct] * m.element[cm];
for (int k = 2; k <= cols; k++) {
ct++;
cm += m.cols;
sum += element[ct] * m.element[cm];
}
w.element[cw++] = sum;
ct -= cols - 1; //重置行列数
cm = j;
}
ct += cols; //重置行列数
cm = 0;
}
return w;
} //O(rows*cols*m.cols)
特殊矩阵
- 方阵:行数和列数相等的矩阵
- 对角矩阵diagonal:除了对角线以外的元素都为0
template<class T>
class DiagonalMatrix{
public:
DiagonalMatrix(int size = 10){
n = size;
d = new T [n];
}
~DiagonalMatrix() {delete [] d;} //析构函数
DiagonalMatrix<T>& Store(const T& x, int i, int j);
T Retrieve(int i, int j) const;
private:
int n; //矩阵大小
T *d;
}
template<class T>
DiagonalMatrix<T>& DiagonalMatrix<T>::Store(const T& x, int i, int j){ //保存数据
if (i < 1 || j < 1 || i > n || j > n) //检查是否越界
throw OutOfBounds();
if (i != j && x != 0) //如果不在对角线上
throw MustBeZero();
if (i == j)
d[i-1] = x;
return *this;
} //O(1)
template <class T>
T DiagonalMatrix<T>::Retrieve(int i, int j) const{ //获取元素
if (i < 1 || j < 1 || i > n || j > n) //检查是否越界
throw OutOfBounds();
if (i == j)
return d[i-1];
else return 0; //不在对角线上的都是0
} //O(1)
- 三对角矩阵tridiagonal:除了主对角线、上对角线、下对角线以外的元素都为0
存储:行主映射、列主映射、对角线映射 template<class T>
class TridiagonalMatrix {
public:
TridiagonalMatrix(int size = 10){
n = size;
t = new T [3*n-2]; //分配存储空间
}
~TridiagonalMatrix() {delete [] t;}
TridiagonalMatrix<T>& Store (const T& x, int i, int j);
T Retrieve(int i, int j) const;
private:
int n; //矩阵大小
T *t; //用一维数组来存储矩阵
};
template<class T>
TridiagonalMatrix<T>& TridiagonalMatrix<T>::Store(const T &x,int I,int j){
if(I<1||j<1||I>n||j>n) //检查是否越界
throw OutOfBounds();
switch(I-j){ //在哪一条对角线上
case 1:
t[i-2]=x; //矩阵中元素和一位数组的位置的映射关系
break;
case 0:
t[n+I-2]=x;
break;
case -1:
t[2*n+I-2]=x;
break;
default: //如果不在三条对角线上
if(x!=0)
throw MustBeZero();
}
return *this;
}
template <class T>
T TridiagonalMatrix<T>::Retrieve(int i, int j) const{ //获取元素
if ( i < 1 || j < 1 || i > n || j > n)
throw OutOfBounds();
switch (i - j) {
case 1:
return t[i - 2];
case 0:
return t[n + i - 2];
case -1:
return t[2 * n + i - 2];
default:
return 0;
}
}
- 下三角矩阵lower
template<class T>
class LowerMatrix {
public:
LowerMatrix(int size = 10)
{n = size; t = new T [n*(n+1)/2];}
~LowerMatrix() {delete [] t;}
LowerMatrix<T>& Store(const T& x, int i, int j);
T Retrieve(int i, int j) const;
private:
int n;
T *t;
};
template<class T>
LowerMatrix<T>& LowerMatrix<T>::Store(const T& x, int i, int j){
if ( i < 1 || j < 1 || i > n || j > n)
throw OutOfBounds();
if (i >= j)
t[i*(i-1)/2+j-1] = x;
else if (x != 0)
throw MustBeZero();
return *this;
}
template <class T>
T LowerMatrix<T>::Retrieve(int i, int j) const{
if ( i < 1 || j < 1 || i > n || j > n)
throw OutOfBounds();
if (i >= j)
return t[i*(i-1)/2+j-1];
else
return 0;
}
- 对称矩阵symmetric:只保留一半区域的元素即可
- 高效存储:利用特殊矩阵的特点,转化为在一维数组中的映射关系,如0无需保存,对称矩阵存储的时候只存一半
稀疏矩阵
- 稀疏矩阵:许多元素为0的矩阵,且非0区域结构无规律
- 对应:稠密矩阵
- 应用:关联规则(网购推荐)、微信好友关联、计算机视觉(如图片)
数组描述:三元组
- 通过row,col,value三个元素,压缩存储,只保存非0元素
template<class T>
class SparseMatrix{
friend ostream& operator<<
(ostream&, const SparseMatrix<T>&);
friend istream& operator>>
(istream&, SparseMatrix<T>&);
public:
SparseMatrix(int maxTerms = 10);
~SparseMatrix() {delete [] a;}
void Transpose(SparseMatrix<T> &b) const;
void Add(const SparseMatrix<T> &b, SparseMatrix<T> &c) const;
private:
void Append(const Term<T>& t);
int rows, cols; //矩阵的大小
int terms; //非0元素的个数
Term<T> *a; //非0元素组成的数组
int MaxTerms; //非0元素组成的数组的大小
};
template<class T>
SparseMatrix<T>::SparseMatrix(int maxTerms){ //构造函数
if (maxTerms < 1) //检查合法性
throw BadInitializers();
MaxTerms = maxTerms;
a = new Term<T> [MaxTerms]; //创建数组
terms = rows = cols = 0;
}
template <class T>
ostream& operator<<(ostream& out,const SparseMatrix<T>& x){ //重载输出
out << "rows = " << x.rows << " columns = "<< x.cols << endl;
out << "nonzero terms = " << x.terms << endl;
for (int i = 0; i < x.terms; i++)
out << "a(" << x.a[i].row << ',' << x.a[i].col<< ") = " << x.a[i].value << endl;
return out;
} //O(terms)
template<class T>
istream& operator>>(istream& in, SparseMatrix<T>& x){ //重载输入
cout << "Enter number of rows, columns, and terms"<< endl;
in >> x.rows >> x.cols >> x.terms;
if (x.terms > x.MaxTerms)
throw NoMem();
for (int i = 0; i < x.terms; i++) {
cout << "Enter row, column, and value of term " << (i + 1) << endl;
in >> x.a[i].row >> x.a[i].col >> x.a[i].value;
}
return in;
} //O(terms)
- 空间复杂度:每个元素2*sizeof(int)+sizeof(T)
- 时间复杂度:store(O(k)), reverse(O(log k)) (k: 非0元素数目)
- 转置算法:M'的行主次序存储 ➡️ M的列主次序存储
template<class T>
void SparseMatrix<T>::Transpose(SparseMatrix<T> &b) const{
if (terms > b.MaxTerms) //检查空间是否足够
throw NoMem();
b.cols = rows;
b.rows = cols;
b.terms = terms;
int *ColSize, *RowNext;
//Colsize:原矩阵每列的非0元素数目
//RowNext:转置矩阵每行中,下一个非0元素在b中的位置
ColSize = new int[cols + 1];
RowNext = new int[cols + 1];
for(int I=1;i<=cols;i++)
ColSize[I]=0;
for(int I=0;i<terms;i++) //terms:非0元素的数目
ColSize[a[I].col]++; //原矩阵中的非0元素列表
RowNext[1]=0;
for(I=2;i<=cols;i++)
RowNext[I]=RowNext[I-1]+ColSize[I-1];
for(I=0;i<terms;i++){ //遍历所有非0元素
int j=RowNext[a[I].col]; //找到它在新矩阵的位置
b.a[j].row=a[I].col;
b.a[j].col=a[I].row;
b.a[j].value=a[I].value;
RowNext[a[I].col]++; //更新位置,否则会覆盖原来的元素
}
} //O(cols+terms)
//原来大矩阵的转置的复杂度:O(rows*cols)
- 在尾部添加新元素
template<class T>
void SparseMatrix<T>::Append(const Term<T>& t){
if (terms >= MaxTerms) throw NoMem();
a[terms] = t;
terms++;
} //O(1)
- 不足:分配更大空间,数据复制效率低
链表描述
template<class T>
class CNode {
friend LinkedMatrix<T>;
friend ostream& operator<<
(ostream&, const LinkedMatrix<T>&);
friend istream& operator>>
(istream&, LinkedMatrix<T>&);
public:
int operator !=(const CNode<T>& y)
{return (value != y.value);}
void Output(ostream& out) const
{out << "column " << col << " value " << value;}
private:
int col;
T value;
};
template<class T>
ostream& operator<<(ostream& out, const CNode<T>& x){
x.Output(out); out << endl;
return out;
}
template<class T>
class HeadNode { //行头节点类
friend LinkedMatrix<T>;
friend ostream& operator<<
(ostream&, const LinkedMatrix<T>&);
friend istream& operator>>
(istream&, LinkedMatrix<T>&);
public:
int operator !=(const HeadNode<T>& y)
{return (row != y.row);}
void Output(ostream& out) const
{out << "row " << row;}
private:
int row;
Chain<CNode<T> > a; //行链表
};
template<class T>
ostream& operator<<(ostream& out, const HeadNode<T>& x){
x.Output(out);
out << endl;
return out;
}
template<class T>
class LinkedMatrix {
friend ostream& operator<<(ostream&, const LinkedMatrix<T>&);
friend istream& operator>>(istream&, LinkedMatrix<T>&);
public:
LinkedMatrix(){}
~LinkedMatrix(){}
void Transpose(LinkedMatrix<T> &b) const;
private:
int rows, cols; //矩阵大小
Chain<HeadNode<T> > a; //行头节点链表
};
作业3
将下三角矩阵转置成上三角矩阵
/*
1 0 0 0 0 0 0 0 0 0
1 2 0 0 0 0 0 0 0 0
1 2 3 0 0 0 0 0 0 0
1 2 3 4 0 0 0 0 0 0
1 2 3 4 5 0 0 0 0 0
1 2 3 4 5 6 0 0 0 0
1 2 3 4 5 6 7 0 0 0
1 2 3 4 5 6 7 8 0 0
1 2 3 4 5 6 7 8 9 0
1 2 3 4 5 6 7 8 9 1
*/
template<typename T>
class UpperMatrix{ //上三角矩阵类
private:
int n;
T *t;
public:
UpperMatrix(int size=10){
n=size;
t=new T[n*(n+1)/2]; //分配数组空间
}
~UpperMatrix(){
delete[] t;
}
UpperMatrix<T>& store(const T& x,int i,int j);
T retrive(int i,int j) const;
};
template<typename T>
UpperMatrix<T>& UpperMatrix<T>::store(const T& x,int i,int j){
if(i<1||j<1||i>n||j>n){ //检查是否越界
cout<<"Out of bounds!";
return *this;
}
if(j>=i) //上三角
t[64-(11-i)*(12-i)/2-j]=x;
else if (x != 0) //除上三角以外的元素如果非0
cout<<"Must be zero!";
return *this;
}
template<typename T>
T UpperMatrix<T>::retrive(int i, int j) const{ //获取元素
if(i<1||j<1||i>n||j>n){
cout<<"Out of bounds!";
return 0;
}
if(j>=i)
return t[64-(11-i)*(12-i)/2-j];
else
return 0;
}
template<typename T>
class LowerMatrix { //下三角矩阵类
public:
LowerMatrix(int size = 10){
n=size;
t=new T[n*(n+1)/2];
}
~LowerMatrix() {
delete[] t;
}
LowerMatrix<T>& store(const T& x, int i, int j);
T retrieve(int i, int j) const;
UpperMatrix<T> transpose();
private:
int n;
T *t;
};
template<class T>
LowerMatrix<T>& LowerMatrix<T>::store(const T& x, int i, int j){
if (i< 1||j< 1||i>n||j>n){
cout<<"Out of bounds!";
return *this;
}
if (i >= j)
t[i*(i-1)/2+j-1] = x;
else if (x != 0)
cout<<"Must be zero!";
return *this;
}
template <class T>
T LowerMatrix<T>::retrieve(int i, int j) const{
if (i< 1||j< 1||i>n||j>n){
cout<<"Out of bounds!";
return 0;
}
if (i >= j)
return t[i*(i-1)/2+j-1];
else
return 0;
}
template<typename T>
UpperMatrix<T> LowerMatrix<T>::transpose(){ //转置
UpperMatrix<T> u;
for(int i=1;i<=10;i++)
for(int j=1;j<=i;j++)
u.store(retrieve(i, j), j, i); //将行列转置存储到上三角矩阵中
return u; //返回上三角矩阵
}
int main(){
cout<<"Please input a lower matrix!"<<endl;
int t;
LowerMatrix<int> m;
for(int i=1;i<=10;i++)
for(int j=1;j<=10;j++){
cin>>t;
m.store(t, i, j);
}
UpperMatrix<int> u=m.transpose();
for(int i=1;i<=10;i++){
for(int j=1;j<=10;j++)
cout<<u.retrive(i, j)<<" ";
cout<<endl;
}
}
稀疏矩阵的乘法
/*
1 2 3
4 5 6
7 8 9
2 3 4
5 6 7
1 3 12
4 6 42
1 2 3
1 3 4
4 5 6
2 3 4
3 3 2
1 3 20
*/
template<typename T>
class Term {
public:
int row,col;
T value;
Term(){}
Term(int r,int c,T v){
row=r;
col=c;
value=v;
}
};
template<typename T>
class SparseMatrix {
public:
SparseMatrix(int maxTerms = 10);
void Set(int r,int c);
void Append(const Term<T>& t);
SparseMatrix<T> operator*(const SparseMatrix<T>& s) const;
void Output();
private:
int rows, cols; //矩阵的大小
int terms; //非0元素的个数
Term<T> *a; //非0元素组成的数组
int MaxTerms; //非0元素组成的数组的大小
};
template<typename T>
SparseMatrix<T>::SparseMatrix(int maxTerms) { //构造函数
if(maxTerms<1) //检查合法性
cout<<"Wrong!"<<endl;
MaxTerms=maxTerms;
a=new Term<T> [MaxTerms]; //创建数组
terms=0;
}
template<typename T>
void SparseMatrix<T>::Set(int r, int c){
rows=r;
cols=c;
}
template<typename T>
void SparseMatrix<T>::Append(const Term<T> &t){
if(terms>MaxTerms){
cout<<"Out of bounds!";
return ;
}
a[terms].row=t.row;
a[terms].col=t.col;
a[terms].value=t.value;
terms++;
}
template<typename T>
SparseMatrix<T> SparseMatrix<T>::operator*(const SparseMatrix<T> &s) const{
SparseMatrix<T> ans;
if(cols!=s.rows) {
cout<<"Wrong!"<<endl;
return ans;
}
ans.rows=rows;
ans.cols=s.cols;
for(int i=0;i<terms;i++){ //遍历第一个矩阵的非0元素
//在第二个矩阵中找到行数和第一个矩阵元素列数相同的元素相乘,存到对应的地方
for(int j=0;j<s.terms;j++){
if(s.a[j].row==a[i].col){
T mul=a[i].value*s.a[j].value;
Term<T> t(a[i].row,s.a[j].col,mul);
//该元素的下标在ans矩阵中是否重复
int k;
for(k=0;k<ans.terms;k++)
if(ans.a[k].row==a[i].row&&ans.a[k].col==s.a[j].col){
ans.a[k].value+=mul;
break;
}
if(k==ans.terms)
ans.Append(t);
}
}
}
return ans;
}
template<typename T>
void SparseMatrix<T>::Output(){
for(int i=0;i<terms;i++)
cout<<"a("<<a[i].row<<','<<a[i].col<<")="<<a[i].value<<endl;
}
int main(){
SparseMatrix<int> s1,s2,s3;
int r,c,v;
cout<<"Please set size for sparse matrix 1!"<<endl;
cin>>r>>c;
s1.Set(r, c);
cout<<"Please set size for sparse matrix 2!"<<endl;
cin>>r>>c;
s2.Set(r, c);
cout<<"Please input sparse matrix 1!"<<endl;
for(int i=1;i<=3;i++){
cin>>r>>c>>v;
Term<int> t(r,c,v);
s1.Append(t);
}
cout<<"Please input sparse matrix 2!"<<endl;
for(int i=1;i<=2;i++){
cin>>r>>c>>v;
Term<int> t(r,c,v);
s2.Append(t);
}
s3=s1*s2;
s3.Output();
return 0;
}
用LinkedMatrix实现稀疏矩阵
//未完成
template<typename T>
class Chain;
template<typename T>
class LinkedMatrix;
template<typename T>
class ColNode;
template<typename T>
class HeadNode;
template<typename T>
class Node{ //节点类
public:
T data;
Node *next;
};
template<typename T>
class Chain{ //普通链表类
public:
Chain(){
head=NULL;
}
void Append(T t); //链表增加节点
void Output(); //输出链表
T* Find(T n);
Node<T> *head; //头节点
};
template<typename T>
void Chain<T>::Append(T t){
Node<T>* p;
p->data=t;
p->next=NULL;
if(head==NULL){
head=p;
return ;
}
Node<T> *tail=head;
while(tail->next)
tail=tail->next;
tail->next=p;
}
template<typename T>
void Chain<T>::Output(){
Node<T>* p=head;
while(p){
cout<<p->data; //不同类型的数据需要重载<<
p=p->next;
}
}
template<typename T>
T* Chain<T>::Find(T n){
Node<T>* p=head;
while(!p){
if(p->data==n) //需要重载==
return &(p->data);
p=p->next;
}
return NULL;
}
template<typename T>
class ColNode{ //列节点类
friend ostream& operator<<(ostream& out,const ColNode<T>& x);
public:
int col;
T value;
void Output(){
cout<<col<<" )= "<<value<<endl;
}
};
template<typename T>
ostream& operator<<(ostream& out,const ColNode<T>& x){
out<<x.col<<" )= "<<x.value<<endl;
return out;
}
template<typename T>
class HeadNode{ //头节点类
friend ostream& operator<<(ostream& out,const HeadNode<T>& x);
public:
int row;
Chain<ColNode<T>> a; //每一个头节点有一个列链表
void Output(){
Node<ColNode<T>> *p=a.head;
while(!p){
cout<<"( "<<row<<", ";
a.Output();
}
}
void AddCol(int c,T v); //在同一行增加列节点
bool operator==(const HeadNode<T>& x) const{
if(x.row==row)
return true;
return false;
}
};
template<typename T>
ostream& operator<<(ostream& out,const HeadNode<T>& x){
out<<"( "<<x.row<<", ";
cout<<x.a;
return out;
}
template<typename T>
void HeadNode<T>::AddCol(int c,T v){
ColNode<T> n;
n.col=c;
n.value=v;
a.Append(n);
}
template<typename T>
class LinkedMatrix{
public:
int rows,cols;
Chain<HeadNode<T>> a; //行头节点链表
LinkedMatrix();
void Input(); //输入稀疏矩阵
void Append(int r,int c,T v); //增加行节点
HeadNode<T>* Find(int r); //返回找到的头节点或是NULL
void Output(); //输出稀疏矩阵
LinkedMatrix<T> operator+(const LinkedMatrix<T>& m) const;
LinkedMatrix<T> operator-(const LinkedMatrix<T>& m) const;
LinkedMatrix<T> operator*(const LinkedMatrix<T>& m) const;
};
template<typename T>
LinkedMatrix<T>::LinkedMatrix(){
rows=cols=0;
}
template<typename T>
void LinkedMatrix<T>::Append(int r, int c, T v){
HeadNode<T> t;
if(!Find(r)){ //如果该行还没有存储过
t.row=r;
a.Append(t); //加到头节点链表中
}
t.AddCol(c, v); //头节点的列节点链表中增加一个列节点
}
template<typename T>
HeadNode<T>* LinkedMatrix<T>::Find(int r){
HeadNode<T> h;
h.row=r;
return a.Find(h);
}
template<typename T>
void LinkedMatrix<T>::Input(){
int terms;
cout<<"Please enter the number of rows, columns, and terms!"<<endl;
cin>>rows>>cols>>terms;
HeadNode<T> h;
for(int i=1;i<=terms;i++){
cout<<"Please enter the row, column, and value of this term!"<<endl;
int row,col;
T value;
cin>>row>>col>>value;
Append(row, col, value);
}
}
template<typename T>
void LinkedMatrix<T>::Output(){
cout<<"rows: "<<rows<<" columns: "<<cols<<endl;
a.Output();
}
int main(){
LinkedMatrix<int> M;
M.Input();
M.Output();
return 0;
}