三元组链式存储稀疏矩阵


数组是由类型相同的数据元素构成的有序集合,每个元素称为数组元素,每个元素受n(n>=0)个线性表的约束,每个元素在n个线性关系中的序号称为该元素的下标,可以通过下标访问该数据元素。数组中的数据元素本身还可以是具有某种结构的,但要属于同一数据类型,因此数组可以被看做线性表的推广。

对一个矩阵结构显然用一个二维数组来表示是非常恰当的,但在有些情况下,比如常见的一些特殊矩阵,如三角矩阵、对称矩阵、带状矩阵、稀疏矩阵,从节省存储空间的角度考虑,这种存储不太合适。

如果m×n矩阵中有t个非零元素且t<<m×n,这样的矩阵称为稀疏矩阵。很多科学管理及工程计算中,常会遇到阶数很高的大型稀疏矩阵。如果按常规分配方法,顺序分配在计算机内,那将是相当浪费内存的。所以一般对稀疏矩阵采取三元组和十字链表的存储方式。

三元组表存储结构如下:

typedef  struct

{  int  r, c;       /*行号、列号*/

   ElemType  d;  /*非零元素值*/

}TupNode;

typedef  struct

{  int  rows,cols,nums;  /*行数、列数、非零元素个数*/

   TupNode  data[maxsize];  /*三元组表*/

}TSMatrix;


程序代码如下:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
typedef int ElemType;

typedef  struct
{  int  r, c;       /*行号、列号*/
   ElemType  d;  /*非零元素值*/
}TupNode;
typedef  struct
{  int  rows,cols,nums;  /*行数、列数、非零元素个数*/
   TupNode  *p;  /*三元组表*/
}TSMatrix;
void initMatrix(TSMatrix &m){
    // cout<<"请输入矩阵的行数,列数和非零元素的个数:(行数,列数,非零元素个数):"<<endl;
    cin>>m.rows>>m.cols>>m.nums;
    m.p =(TupNode*)malloc(m.nums*sizeof(TupNode));
    cout<<"请输入矩阵对应行列位置的元素值:行号,列好,非零值:"<<endl;
    for(int i = 0;i < m.nums;i++){
        cin>>m.p[i].r>>m.p[i].c>>m.p[i].d;
    }
}
void output(TSMatrix &m){
    int i,j,k;
    for(i=0;i<m.rows;i++){
        for(j=0;j<m.cols;j++){
             for(k=0;k<m.nums;k++){
                if(i==m.p[k].r && j==m.p[k].c){
                    break;
                }
             }
             if(k<m.nums){
                printf("%d\t",m.p[k].d);
             }else{
                printf("0\t");
             }
        }
        printf("\n");
    }
}

void addSMatrix(const TSMatrix &M,const TSMatrix &N, TSMatrix &Q) {
    if (M.rows != N.rows || M.cols != N.cols){
        cout<<"两个矩阵行列不相等,无法进行相加减。"<<endl;
    }
    Q.p =(TupNode*)malloc(Q.nums*sizeof(TupNode));
    Q.rows = M.rows;
    Q.cols = M.cols;
    Q.nums = 0;
    int mnums=0, nnums=0;
    while (mnums<M.nums && nnums<N.nums)
    {
        if (M.p[mnums].r < N.p[nnums].r) {
            Q.p[Q.nums] = M.p[mnums];
            Q.nums++;mnums++;
        }
        else if (M.p[mnums].r > N.p[nnums].r) {
            Q.p[Q.nums] = N.p[nnums];
            Q.nums++;nnums++;
        }
        else {
            if (M.p[mnums].c < N.p[nnums].c) {
                Q.p[Q.nums] = M.p[mnums];
                Q.nums++;mnums++;
            }
            else if (M.p[mnums].c > N.p[nnums].c) {
                Q.p[Q.nums] = N.p[nnums];
                Q.nums++;nnums++;
            }
            else
            {
                if (M.p[mnums].d + N.p[nnums].d == 0) { ++mnums; ++nnums; }
                else
                {
                    Q.p[Q.nums] = M.p[mnums];
                    Q.p[Q.nums].d += N.p[nnums].d;
                    Q.nums++;mnums++;nnums++;
                }
            }
        }
    }
    while (mnums< M.nums)
    {
        Q.p[Q.nums] = M.p[mnums];
        Q.nums++;mnums++;
    }
    while (nnums < N.nums)
    {
        Q.p[Q.nums] = N.p[nnums];
        Q.nums++;nnums++;
    }
}
void subSMatrix(const TSMatrix &M,const TSMatrix &N, TSMatrix &Q) {
    if (M.rows != N.rows || M.cols != N.cols){
        cout<<"两个矩阵行列不相等,无法进行相加减。"<<endl;
    }
    Q.p =(TupNode*)malloc(Q.nums*sizeof(TupNode));
    Q.rows = M.rows;
    Q.cols = M.cols;
    Q.nums = 0;
    int mnums=0, nnums=0;
    while (mnums<M.nums && nnums<N.nums)
    {
        if (M.p[mnums].r < N.p[nnums].r) {
            Q.p[Q.nums] = M.p[mnums];
            Q.nums++;mnums++;
        }
        else if (M.p[mnums].r > N.p[nnums].r) {
            Q.p[Q.nums] = N.p[nnums];
            Q.nums++;nnums++;
        }
        else {
            if (M.p[mnums].c < N.p[nnums].c) {
                Q.p[Q.nums] = M.p[mnums];
                Q.nums++;mnums++;
            }
            else if (M.p[mnums].c > N.p[nnums].c) {
                Q.p[Q.nums] = N.p[nnums];
                Q.nums++;nnums++;
            }
            else
            {
                if (M.p[mnums].d - N.p[nnums].d == 0) { ++mnums; ++nnums; }
                else
                {
                    Q.p[Q.nums] = M.p[mnums];
                    Q.p[Q.nums].d -= N.p[nnums].d;
                    Q.nums++;mnums++;nnums++;
                }
            }
        }
    }
    while (mnums< M.nums)
    {
        Q.p[Q.nums] = M.p[mnums];
        Q.nums++;mnums++;
    }
    while (nnums < N.nums)
    {
        Q.p[Q.nums] = N.p[nnums];
        Q.nums++;nnums++;
    }
}
int main()
{
    TSMatrix M;
    TSMatrix N;
    TSMatrix Q;
    cout<<"请选择:"<<endl;
    cout<<"\t"<<"1、矩阵加法"<<"\t"<<"2、矩阵减法"<<endl;
    int choice;
    cin>>choice;
    switch (choice)
    {
    case 1:
        cout<<"请输入矩阵M的行数,列数和非零元素的个数:(行数,列数,非零元素个数):"<<endl;
        initMatrix(M);
        output(M);
        cout<<"请输入矩阵N的行数,列数和非零元素的个数:(行数,列数,非零元素个数):"<<endl;
        initMatrix(N);
        output(N);
        cout<<"矩阵M与N的和为:"<<endl;
        addSMatrix(M,N,Q);
        output(Q);
        break;
    case 2:
        cout<<"请输入矩阵M的行数,列数和非零元素的个数:(行数,列数,非零元素个数):"<<endl;
        initMatrix(M);
        output(M);
        cout<<"请输入矩阵N的行数,列数和非零元素的个数:(行数,列数,非零元素个数):"<<endl;
        initMatrix(N);
        output(N);
        subSMatrix(M,N,Q);
        cout<<"矩阵M与N的差为:"<<endl;
        output(Q);
        break;
    default:
        break;
    }
    return 0;
}

运行截图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值