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);
}