数据结构——三元组实现稀松矩阵

#include <iostream>
using namespace std;
const int DefaultSize = 100;
typedef int dt;

struct Trituple {//三元组
    int row, col;
    dt value;
    /*Trituple& operator=(Trituple& x) {
        row = x.row, col = x.col, value = x.value;
    }*/
};
class SparseMatrix {
public:
    friend ostream& operator << (ostream& out, SparseMatrix& x);
    friend istream& operator >> (istream& in, SparseMatrix& x);

    SparseMatrix(int maxSize = DefaultSize);
    SparseMatrix(SparseMatrix& x);
    ~SparseMatrix() { delete[]smArray; }
    SparseMatrix Transpose();
    SparseMatrix FastTranspose();
    SparseMatrix& operator=(SparseMatrix& x);
    SparseMatrix Add(SparseMatrix& x);
    SparseMatrix Multiply(SparseMatrix& x);
private:
    int Rows, Cols, Terms;
    Trituple* smArray;
    int maxTerms;
};
SparseMatrix::SparseMatrix(int maxSize):maxTerms(maxSize) {
    if (maxSize < 1) {
        cerr << "初始化错误" << endl; exit(1);
    }
    smArray = new Trituple[maxSize];
    if(smArray==NULL) {
        cerr << "存储分配错误" << endl; exit(1);
    }
    Rows = Cols = Terms = 0;
}
SparseMatrix::SparseMatrix(SparseMatrix& x) {
    Rows = x.Rows; Cols = x.Cols; Terms = x.Terms; maxTerms = x.maxTerms;
    smArray = new Trituple[maxTerms];
    if (smArray == NULL) {
        cerr << "存储分配错误" << endl; exit(1);
    }
    for (int i = 0; i < Terms; i++)smArray[i] = x.smArray[i];
}

SparseMatrix SparseMatrix::Transpose() {
    SparseMatrix b(maxTerms);
    b.Rows = Cols;
    b.Cols = Rows;
    b.Terms = Terms;
    if (Terms) {
        int k, i, currenntB = 0;
        for(k=0;k<Cols;k++)
            for (i = 0; i < Terms; i++)
                if (smArray[i].col = k) {
                    b.smArray[currenntB].row = k;
                    b.smArray[currenntB].col = smArray[i].row;
                    b.smArray[currenntB++].value = smArray[i].value;
                }
    }
    return b;
}
SparseMatrix SparseMatrix::FastTranspose() {
    //对稀疏矩阵( * this 指示)做快速转置,结果放在b中并通过函数返回
    int* rowSize = new int[Cols];//辅助数组,统计各列非零元素个数
    int* rowStart = new int[Cols];//辅助数组,预计转置后各行存放位置
    SparseMatrix b(maxTerms); // 1存放转置结果
    b.Rows = Cols;
    b.Cols = Rows;
    b.Terms = Terms;
    if (Terms > 0) {
        int i, j;
        for (i = 0; i < Cols; i++) rowSize[i] = 0;
        for (i = 0; i < Terms; i++) rowSize[smArray[i].col]++;
        rowStart[0] = 0;
        for (i = 1; i < Cols; i++)
            rowStart[i] = rowStart[i - 1] + rowSize[i - 1];
        for (i = 0; i < Terms; i++) {//从a向b传送
            j = rowStart[smArray[i].col]; //第1个非零元素在b中应放位置
            b.smArray[j].row = smArray[i].col;
            b.smArray[j].col = smArray[i].row;
            b.smArray[j].value = smArray[i].value;
            rowStart[smArray[i].col] ++;
        }
    }
    delete[] rowSize; delete[]rowStart;
    return b;
}  
SparseMatrix& SparseMatrix::operator=(SparseMatrix& x) {
    Rows = x.Rows; Cols = x.Cols; Terms = x.Terms; maxTerms = x.maxTerms;
    smArray = new Trituple[maxTerms];
    if (smArray == NULL) {
        cerr << "存储分配错误" << endl; exit(1);
    }
    for (int i = 0; i < Terms; i++)smArray[i] = x.smArray[i];
}
SparseMatrix SparseMatrix::Add(SparseMatrix& b) {
    //两个稀疏矩阵A ( * this指示)与B (参数表中的b)相加,结果在Result中
    SparseMatrix result;
    result.Rows = Rows;
    result.Cols = Cols;
    //结果矩阵的三元组表
    if (Rows != b.Rows || Cols != b.Cols) {
        cout << "Incompatible matrices" << endl; //两个 矩阵规格不一样
        return result;//返回空矩阵
    }
    int i = 0, j = 0, index_a, index_b;
    result.Terms = 0;
    while (i < Terms && j < b.Terms) {
        index_a = Cols * smArray[i].row + smArray[i].col;
        index_b = Cols * b.smArray[j].row + b.smArray[j].col;
        if (index_a < index_b) {
            result.smArray[result.Terms] = smArray[i];
            i++;
        }
        else if (index_a > index_b) {
            result.smArray[result.Terms] = b.smArray[j];
            j++;
        }
        else {
            result.smArray[result.Terms] = smArray[i];
            result.smArray[result.Terms].value = smArray[i].value + b.smArray[j].value;
            i++, j++;
        }
        result.Terms++;
    }
    //复制剩余元素。
    for (; i < Terms; i++) {
        result.smArray[result.Terms] = smArray[i]; result.Terms++;
    }
    for (; j < b.Terms; j++) {
        result.smArray[result.Terms] = b.smArray[i]; result.Terms++;
    }
    return result;
}
  
SparseMatrix SparseMatrix::Multiply(SparseMatrix& b) {
    //两个稀疏矩阵A ( * this指示)与B (参数表中的b)相加,结果在Result中
    SparseMatrix result;
    result.Rows = Rows;
    result.Cols = b.Cols;
    //结果矩阵的三元组表
    if (Cols != b.Rows) {
        cerr << "Incompatible matrices" << endl;//A列数与B行数不等
        return result;// 返回空矩阵
    }
    if (Terms == maxTerms || b.Terms == maxTerms) {
        cerr << "One additional space inaor b needed" << endl;
        return result;
        //空间不足,返回空矩阵
    }
    int* rowSize = new int[b.Rows];//矩阵 B各行非零元素个数
    int* rowStart = new int[b.Rows + 1];//矩阵B各行在三元组开始位置
    dt* temp = new dt[b.Cols];
    //暂存每一行计算结果
    int i, Current, lastInResult, RowA, ColA, ColB;
    for (i = 0; i < b.Rows; i++) rowSize[i] = 0;
    for (i = 0; i < b.Terms; i++) rowSize[b.smArray[i].row]++;
    rowStart[0] = 0;
    //B第i行非零元素开始位置
    for (i = 1; i <= b.Rows; i++)
        rowStart[i] = rowStart[i - 1] + rowSize[i - 1];
    Current = 0; lastInResult = -1;//a扫描指针及result存指针
    while (Current < Terms) { //生成result的当前行temp
        RowA = smArray[Current].row; //当前行的行号
        for (i = 0; i < b.Cols; i++) temp[i] = 0;
        while (Current < Terms && smArray[Current].row == RowA) {
            ColA = smArray[Current].col; //矩阵 A当前扫描到元素的列号
            for (i = rowStart[ColA]; i < rowStart[ColA + 1]; i++) {
                ColB = b.smArray[i].col; //矩阵B中相乘元素的列号
                temp[ColB] += smArray[Current].value * b.smArray[i].value;
            }
        }//A的RowA行与B的ColB列相乘
        Current++;
    }
    for (i = 0; i < b.Cols; i++)
        if (temp[i] != 0) {//将temp中的非零元素压缩到result中去
            lastInResult++;
            result.smArray[lastInResult].row = RowA;
            result.smArray[lastInResult].col = i;
            result.smArray[lastInResult].value = temp[i];
        }
    result.Rows = Rows; result.Cols = b.Cols;
    result.Terms = lastInResult + 1;
    delete[]rowSize, delete[]rowStart, delete[]temp;
    return result;
}

ostream& operator<<(ostream& out, SparseMatrix& x) {
    out << "rows= " << x.Rows
        << " cols= " << x.Cols
        << " Terms= " << x.Terms << endl;
    for (int i = 0; i < x.Terms; i++)
        out << "M[" << x.smArray[i].row << "][" << x.smArray[i].col
            << "]= " << x.smArray[i].value << endl;
    return out;
}
istream& operator>>(istream& in, SparseMatrix& x) {
    cout << "输入行列和不为零的数字个数" << endl;
    in >> x.Rows >> x.Cols >> x.Terms;
    if (x.Terms > x.maxTerms) {
        cerr << "输入大小错误" << endl; exit(1);
    }
    for (int i = 0; i < x.Terms; i++) {
        cout << "输入行列和该位置数字" << endl;
        in >> x.smArray[i].row >> x.smArray[i].col >> x.smArray[i].value;
    }
    return in;
}
int main(){
    SparseMatrix sq1,sq2,sq3;
    cin >> sq1>>sq2;
    cout << sq1<<sq2<<endl;
    sq3=sq1.Add(sq2);
    cout <<sq3<< sq1 << sq2 << endl;
    sq2.FastTranspose();
    cout << sq2 << endl;
    sq3 = sq1.Multiply(sq2);
    cout <<sq3<< sq1 << sq2 << endl;

}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值