/*
以下是用于测试的两个稀疏矩阵
3 0 0 5
M= 0 -1 0 0 (M矩阵)
2 0 0 0
-3 0 2 0
N= 0 5 0 0 (N矩阵)
0 0 0 -1
M=M+N
0 0 2 5
M= 0 4 0 0 (相加后的M矩阵)
2 0 0 -1
以上是矩阵表示图
M.chead(colhead) 1 2 3 4
M.rhead(rowhead)
1 1 1 3 1 4 5(分别表示行列和该位置的值)
2 2 2 -1
3 3 1 -2
N.chead(colhead) 1 2 3 4
N.rhead(rowhead)
1 1 1 -3 1 3 2
2 2 2 5
3 3 4 -1
M矩阵相加后
M.chead(colhead) 1 2 3 4
M.rhead(rowhead)
1 1 3 2 1 4 5
2 2 2 4
3 3 1 -2 3 4 -1
以上是三元表示形式 压缩的最后表现方式 忽略了矩阵中的零元
*/
#include<stdio.h>
#include<stdlib.h>
//宏定义
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef struct OLNode //替换一个结构体的名字
{
int i,j,e; //矩阵三元组i代表行 j代表列 e代表当前位置的数据
struct OLNode *right,*down; //指针域 右指针 下指针
}OLNode,*OLink; //结构体的新名
typedef struct
{
OLink *rhead,*chead; //行和列链表头指针由CreateSMatrix分配
int mu,nu,tu; //稀疏矩阵的行数,列数和非零元的个数
}CrossList;
Status CreateMatrix_OL(CrossList *M);
Status AddSMatrix(CrossList *M,CrossList *N);
void main()
{
CrossList M,N;
int i;
OLNode *p;
printf("输入测试矩阵:\n");
CreateMatrix_OL(&M);
printf("输入测试矩阵:\n");
CreateMatrix_OL(&N);
AddSMatrix(&M,&N);
printf("输出测试矩阵:\n");
printf("M:\n---------------------\ni\tj\te\n---------------------\n");
//printf("%d\n\n",M.rhead[2]->e);
for (i=1;i<=M.nu;i++)
{
if (NULL!=M.chead[i])
{
p=M.chead[i];
while (NULL!=p)
{
printf("%d\t%d\t%d\n",p->i,p->j,p->e);
p=p->down;
}
}
}
getchar();
getchar();
}
Status CreateMatrix_OL(CrossList *M) //创建系数矩阵M,采用十字链表存储表示
{
int m,n,t; //定义矩阵的行,列,非零元的数量
int i,j,e; //定义中间变量
OLNode *p,*q; //定义中间变量
// if(M)
//{
// free(M); //如果矩阵已经存在,那么释放矩阵
//}
scanf("%d%d%d",&m,&n,&t); //输入矩阵的行列及非零元的数量
M->mu=m;
M->nu=n;
M->tu=t; //初始化矩阵的行列及非零元的数量
if(!(M->rhead=(OLink*)malloc((m+1)*sizeof(OLink))))
{
exit(OVERFLOW); //初始化矩阵的行链表
}
if(!(M->chead=(OLink*)malloc((n+1)*sizeof(OLink))))
{
exit(OVERFLOW); //初始化矩阵的列链表
}
for(i=1;i<=m;i++)
{
M->rhead[i]=NULL; //初始化行
}
for(j=1;j<=n;j++)
{
M->chead[j]=NULL; //初始化列
}
for(scanf("%d%d%d",&i,&j,&e);0!=i;scanf("%d%d%d",&i,&j,&e)) //输入三元组 直到行为0结束
{
if(!(p=(OLNode*)malloc(sizeof(OLNode))))
{
exit(OVERFLOW); //动态生成p
}
p->i=i;
p->j=j;
p->e=e; //初始化p
if(NULL==M->rhead[i]||M->rhead[i]->j>j)
{
p->right=M->rhead[i];
M->rhead[i]=p;
}
else
{
for(q=M->rhead[i];(q->right)&&q->j>j;q=q->right);
p->right=q->right;
q->right=p;
}
if(NULL==M->chead[j]||M->chead[j]->i>i)
{
p->down=M->chead[j];
M->chead[j]=p;
}
else
{
for (q=M->chead[j];(q->down );q=q->down);
p->down=q->down;
q->down=p;
}
}
return OK;
}
Status AddSMatrix(CrossList *M,CrossList *N)
{
int i,j;
OLNode *p,*q,*temp;
if (M->mu!=N->mu||M->nu!=N->nu)
{
exit(OVERFLOW);
}
M->tu+=N->tu;
for (i=1;i<=N->mu;i++)
{
p=N->rhead[i];
while(NULL!=p)
{
if(NULL==M->rhead[p->i]||M->rhead[p->i]->j>p->j)
{
p->right=M->rhead[p->i];
M->rhead[p->i]=p;
}
else if(M->rhead[p->i]->j<p->j)
{
for (q=M->rhead[p->i];(q->right)&&q->j<p->j;q=q->right);
p->right=q->right;
q->right=p;
}
if (NULL==M->chead[p->j]||M->chead[p->j]->i>p->i)
{
p->down=M->chead[p->j];
M->chead[p->j]=p;
}
else if (M->chead[p->j]->i<p->i)
{
for (q=M->chead[p->j];(q->down)&&q->i<p->i;q=q->down);
p->down=q->down;
q->down=p;
}
else
{
M->chead[p->j]->e+=p->e;
M->tu--;
if (0==M->chead[p->j]->e)
{
M->tu--;
M->chead[p->j]=M->chead[p->j]->down;
M->rhead[p->i]=M->chead[p->j]->right;
}
}
p=p->right;
}
}
return OK;
}