西北工业大学NOJ数据结构—012以三元组表作为储存结构实现矩阵相加

本文介绍了一种针对稀疏矩阵进行加法运算的有效算法,该算法利用三元组表形式存储矩阵,并通过遍历比较的方式实现矩阵相加。文章详细解释了算法的逻辑流程,并提供了完整的C语言代码实现。

题意比较清晰,就是用三元组表储存的两个矩阵加一ha(真的很烦,代码打死我)

思路分析:

1.由于要相加的两个三元组表都是给拍好顺序的(很好,非常好),所以只要用两个变量依次遍历两个三元组表就OK了,不需要深层查找是否有相符的

2.设k指向A矩阵的某元素,i指向B矩阵的某元素,如果k的行列都与i相同,就把这两个元素加起来,如果和不为零,就把这个元素放进c,k++,i++

3.如果k的行与i的行相同但是k的列小于i的列,或者k的行小于i的行,说明k在i的前面,把k元素加进C,k++

4.如果k的行与i的行相同但是k的列大于i的列,或者k的行大于i的行,说明i在k的前面,把i元素加进C,i++

5.循环上方几条,直到遍历完A矩阵或者遍历B矩阵,然后哪个矩阵还剩有元素,就把剩下的一股脑加进C

(看起来贼简单,代码重复次数贼多,复制粘贴大法好)

oKOK上代码(づ ̄3 ̄)づ╭❤~

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

typedef struct{//定义三元组
	int i,j;//行列
	int ele;//值
}tri;

typedef struct{//定义三元组表
	tri *data;
	int mu,nu,tu;
}Tritu;

Tritu *creat(int k)//申请一个容量为k的三元组表
{
	Tritu *pa;
	pa=(Tritu*)malloc(sizeof(Tritu));
	pa->data=(tri*)malloc(sizeof(tri)*k);
	pa->tu=k;
	return pa;
}

void add(Tritu *A,Tritu *B,Tritu *C)//将矩阵A加矩阵B的结果输到C
{
	int k=0,i=0;
	int t;
	int c=0;//定义一个c来记录C中到底有多少个元素
	while(k<A->tu&&i<B->tu)//当k小于A表的元素个数i小于B表的元素个数
	{
		if(A->data[k].i==B->data[i].i&&A->data[k].j==B->data[i].j)
		{                     //如果A与B的i,j相同
			t=A->data[k].ele+B->data[i].ele;//就把A与B的元素相加
			if(t!=0)          //如果加和不为零,就把加和放到C中
			{
				C->data[c].i=A->data[k].i;
				C->data[c].j=A->data[k].j;
				C->data[c].ele=t;
				c++;
			}
			k++;i++;
		}
		else if((A->data[k].i==B->data[i].i&&A->data[k].j<B->data[i].j)||A->data[k].i<B->data[i].i){
			C->data[c].i=A->data[k].i;      //如果A与B行数相同但A的列数小于B,或者A的行数小于B
			C->data[c].j=A->data[k].j;      //就把A中元素加入C
			C->data[c].ele=A->data[k].ele;
			c++;
			k++;
		}
		
		else if((A->data[k].i==B->data[i].i&&A->data[k].j>B->data[i].j)||A->data[k].i>B->data[i].i){
			C->data[c].i=B->data[i].i;    //如果A与B行数相同但A的列数大于B,或者A的行数大于B
			C->data[c].j=B->data[i].j;     //就把B中元素加入C
			C->data[c].ele=B->data[i].ele;
			c++;
			i++;
		}
	}
	while(k<A->tu)
	{
		C->data[c].i=A->data[k].i;
		C->data[c].j=A->data[k].j;
		C->data[c].ele=A->data[k].ele;
		k++;
		c++;  //如果A还有剩余就把A依此加入C
	}
	while(i<B->tu)
	{
		C->data[c].i=B->data[i].i;
		C->data[c].j=B->data[i].j;
		C->data[c].ele=B->data[i].ele;
		c++;
		i++;//如果B还有剩余就把B依此加入C
	}
	C->tu=c;
	//printf("%d ",c);
}

void show(Tritu *C)//创建一个函数可以将目标三元组表按顺序输出
{
	int i;
	for(i=0;i<C->tu;i++)
		printf("%d %d %d\n",C->data[i].i,C->data[i].j,C->data[i].ele);
}

int main()
{
	int t1,t2;
	int i=0;
	Tritu *pa,*pb,*pc;
	scanf("%d%d",&t1,&t2);//分别输入A表和B表中元素的个数
	pa=creat(t1);//创建ABC三个三元组表
	pb=creat(t2);
	pc=creat(t1+t2);//这里不确定申请多大 干脆大一点哈哈
	for(i=0;i<t1;i++)//输入A
		scanf("%d %d %d",&pa->data[i].i,&pa->data[i].j,&pa->data[i].ele);
	for(i=0;i<t2;i++)//输入B
		scanf("%d %d %d",&pb->data[i].i,&pb->data[i].j,&pb->data[i].ele);
	add(pa,pb,pc);//AB相加到C函数
	show(pc);
	return 0;
}

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值