数组和广义表(5)行逻辑链接顺序表

本文介绍了一种针对稀疏矩阵的乘法算法,并通过行逻辑链接顺序表的方式存储矩阵,提高了运算效率。该算法首先读取两个输入矩阵的维度及非零元素数量,然后按行读取每个非零元素的具体位置和值。最后通过特定的乘法过程计算出结果矩阵。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >




行逻辑链接的顺序表:

例如:M.data[1]表示矩阵元(1,1,3)只要和N.data[1]表示的矩阵元(1,1,2)想乘;

         而M.data[2]表示矩阵元(1,1,5)则不需要和N中任何元素相乘。因为N.data中没有i为4的元素。

--------------------------------------------------------------------------------------------------------------------------------

代码实现:(后缀名为 .cpp)

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<stdarg.h>

//宏定义
#define OK 1  
#define ERROR 0  
#define TRUE 1  
#define FALSE 0  

#define MAXSIZE 12
#define MAXRC 20

typedef int Status;
typedef int ElemType;

typedef struct{
	int i,j;
	ElemType e;
}Triple;

typedef struct{
	Triple data[MAXSIZE+1];      //非零元单元组表
	int rpos[MAXRC+1];           //各行第一个非零元的位置表
	int mu,nu,tu;                //矩阵的行数、列数、和非零元个数
}RLSMatrix;

//----------------函数实现---------------------
Status CreateTSMatrix(RLSMatrix *M){
	int k,row;
	printf("请输入矩阵的行数:");
	scanf("%d",&M->mu);
	printf("\n请输入矩阵的列数:");
    scanf("%d",& M->nu);
    printf("\n请输入矩阵的非零元个数:");
    scanf("%d",& M->tu);

	for(k=1;k<=M->tu;k++){
		printf("\n请输入第 %d 个非零元的内容: ",k);
		printf("\n请输入行号:");
		scanf("%d",&M->data[k].i);
		printf("\n请输入列号:");
		scanf("%d",&M->data[k].j);
		printf("\n请输入值:");
		scanf("%d",&M->data[k].e);
		
		if(k==1){
			row=M->data[k].i;
			M->rpos[row]=k;
		}

		else if(k>1 && row!=M->data[k].i){
			row=M->data[k].i;
			M->rpos[row]=k;
		}
	}

//	printf("row= %d ",row);
//	for(int i=1;i<=row;i++){
//		printf("%d",M->rpos[i]);
//		printf("\n");
//	}
	return OK;
}


Status PrintTSMatrix(RLSMatrix M)
{
    int k;

    printf(" i  j  v\n");
    for(k = 1;k<= M.tu;k++)
        printf("%2d %2d %2d\n",M.data[k].i,M.data[k].j,M.data[k].e);
	return OK;
}

//求矩阵乘积 Q=M*N,采用行逻辑链接存储表示
Status MultSMatrix(RLSMatrix M,RLSMatrix N,RLSMatrix *Q){
	int Mrow,Nrow,Qcol,tp,tq,p,q;
	int ctemp[15];

	if(M.nu != N.mu ) return ERROR;

	Q->mu=M.mu;  Q->nu=N.nu;  Q->tu=0;     //Q的初始化

	if(M.tu*N.tu !=0){  //Q是非零矩阵
		for(Mrow=1;Mrow<=M.mu;++Mrow){   //处理M的每一行
			for(Qcol=0;Qcol<=N.nu;Qcol++)
				ctemp[Qcol]=0;   //当前行各元素累加器清零
			Q->rpos[Mrow]=Q->tu+1;    // Q 矩阵中的 Mrow 行的第一个元素在数组data[]里面的逻辑顺序
                                // Q.rpos[Mrow], Q.tu表示当前循环多得到的非零元素个数,Q.tu+1则为新的一行开始的逻辑顺序
			
			if(Mrow< M.mu)    
				tp=M.rpos[Mrow+1];    // M矩阵Mrow下一行的第一个元素在M.data[]的卫视
			else
				tp=M.tu+1;   //如果Mrow超过了M的实际拥有行数,那么tp就等于M的非零元素的个数M.tu + 1

			for(p=M.rpos[Mrow];p<tp;p++){    //处理 M 的某一行,从这行的第一个非零元素的逻辑地址
				Nrow=M.data[p].j;            //到下一行第一个非零元素的逻辑地址之间的元素
				
				if(Nrow<N.mu)
					tq=N.rpos[Nrow+1];
				else
					tq=N.tu+1;
				
				for(q=N.rpos[Nrow];q<tq;++q){
					Qcol=N.data[q].j;        //乘积元素在Q中的列号
					ctemp[Qcol]+=M.data[p].e * N.data[q].e;
					//Qcol 是 Q中这一行的每一列的值
				}
			}
			for(Qcol=1;Qcol<=Q->nu;Qcol++)
				if(ctemp[Qcol]){
					if(Q->tu+1 >MAXSIZE) return ERROR;
					++Q->tu;
                    Q->data[Q->tu].i = Mrow;
                    Q->data[Q->tu].j = Qcol;
                    Q->data[Q->tu].e = ctemp[Qcol];
				}//if  
				//将Q这一行的数据进行存储
		}
	}
	return OK;
}

void main(){
    RLSMatrix M,N,Q;

	printf("M矩阵");
    CreateTSMatrix(&M);
    printf("M矩阵的三元组表示为:\n");
    PrintTSMatrix(M);

	printf("N矩阵");
	CreateTSMatrix(&N);
	printf("\nN矩阵的三元组表示为:\n");
    PrintTSMatrix(N);

	MultSMatrix(M,N,&Q);
	printf("Q矩阵");
	printf("\nN矩阵的三元组表示为:\n");
	PrintTSMatrix(Q);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值