数据结构笔记3: 数组和矩阵

数组

多维数组的保存方式

  1. 行主映射
  2. 列主映射

类Array1D

  1. C++数组的缺陷
    (1)越界问题:不能自动检测出越界
    (2)输出问题:不能直接cout
    (3)不支持对数组进行算数操作
  2. 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)
  3. 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)

特殊矩阵

  1. 方阵:行数和列数相等的矩阵
  2. 对角矩阵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)
  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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值