NOJ实验2.4稀疏矩阵的乘法

该代码实现了一个使用链表和三元组结构体处理稀疏矩阵乘法的算法。通过存储每一行的第一个非零元素并维护每个元素的右指针,优化了矩阵的存储和运算效率。程序包括初始化、插入、乘法和显示结果的功能。

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

		NOJ实验 稀疏矩阵的乘法

在这里插入图片描述

思想:借助了十字矩阵数组与链表结合的思想 ,用数组存放每一行的第一个非零元素 ,且对每一个triple 都设置一个 right 域 ,记录该行的下一个元素 ,这样每一行的输出用链表的方式 (为什么要这样? :会发现乱序的只有每一行的列顺序 ,因此只要在这一行内部修改,但若采用数组格式 ,更换顺序是一件麻烦事 ,因此采用链表的插入方式构建)

#include<bits/stdc++.h>
using namespace std;

struct triple {
	int row, col, value;
	triple* right;
};

struct spmat {
	int rows, cols, nums;
	triple* sp;
};
void init(spmat &s)
{
	cin >> s.rows >> s.cols;
	int i = 0,n=s.rows*s.cols;
	s.sp = (triple*)malloc(sizeof(triple) * n);
	triple* p=s.sp;
	for (; i < n; i++)
	{
		cin >> p->row >> p->col >> p->value;
		if (p->row == 0 && p->col == 0 && p->value == 0) break;
		p++;
	}
	s.nums = i;
}
void init(triple** c, int n)
{
	triple** p = c;
	for (int i = 0; i <= n; i++)
	{
		*p = NULL;
		p++;
	}
}
void insertp(triple* &L, triple* term)
{
	triple* prev = L, *p = L->right;
	if (L->col == term->col)L->value += term->value;
	else if (L->col > term->col)
	{
		term->right = L;
		L = term;
	}
	else
	{
		if (p == NULL)
		{
			prev->right = term;
			return;
		}//这一句很重要 ,
		while (p->col < term->col)
		{
			p=p->right;
			prev=prev->right;
			if (p == NULL)
			{
				prev->right = term;
				return;
			}//这一句很重要,
		}
		if (p->col == term->col) p->value += term->value;
		else
		{
			prev->right = term;
			term->right = p;
		}
	}
}
void insertc(triple* a, triple* b, triple** c)
{
	triple* p = (triple*)malloc(sizeof(triple));
	p->right = NULL;
	p->row = a->row; p->col = b->col;p->value= a->value * b->value;
	if (c[p->row] == NULL)
	{
		c[p->row] = p;
	}
	else
	{
		insertp(c[p->row], p);
	}
}
void mul(spmat& a, spmat& b, triple** c)
{
	triple* pa = a.sp, * pb = b.sp,*p;
	while(pa->row!=0)
	{
		pb = b.sp;
		while (pb->row < pa->col) pb++;
		while (pa->col == pb->row)
		{
			insertc(pa,pb,c);
			pb++;
		}
		pa++;
	}
}
void show(triple** c,int n)
{
	triple* p;
	for (int i = 1; i <= n; i++)
	{
		if (c[i] != NULL)
		{
			p = c[i];
			while (p != NULL&&p->value!=NULL)
			{
				cout <<p->row << ' '<< p->col <<' '<< p->value<<endl;
				p = p->right;
			}
		}
	}
}
int main()
{
	spmat a, b;
	init(a);
	init(b);
	triple** c=(triple**)malloc( sizeof(triple*) * (a.rows+1) );
	init(c,a.rows);
	mul(a,b,c);
	show(c,a.rows);
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值