#include "stdafx.h"
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
typedef struct OLNode
{
int i,j;
int e;
struct OLNode *right;
struct OLNode *down;
}OLNode,*OLink;
typedef struct
{
OLink *rhead,*chead; //注意:指针的指针
int mu,nu,tu;
}CrossList;
int Compare(int a,int b)
{
if(a<b)
return -1;
if(a=b)
return 0;
if(a>b)
return 1;
}
void InitSMatrix(CrossList &M)
{
M.rhead=M.chead=NULL;
M.mu=M.nu=M.tu;
}
void DestroySMatrix(CrossList &M)
{
int i;
OLNode *p,*q;
for(i=1;i<=M.mu;i++)
{
p=*(M.rhead+i); //行数组的内容,即每行第一个元素的地址,故取内容
while(p)
{
q=p;
p=p->right;
free(q);
}
}
free(M.rhead);
free(M.chead); //行列数组的内存空间
M.rhead=M.chead=NULL;
M.mu=M.nu=M.tu=0;
}
bool CreateSMatrix(CrossList &M)
{
int i,j,k,m,n,t;
int e;
OLNode *p,*q;
if(M.rhead)
DestroySMatrix(M);
printf("请输入稀疏矩阵的行数 列数 非零元个数:/n");
scanf("%d%d%d",&m,&n,&t);
M.mu=m;
M.nu=n;
M.tu=t;
M.rhead=(OLink *)malloc((m+1)*sizeof(OLink)); //指针的指针
M.chead=(OLink *)malloc((n+1)*sizeof(OLink));
if(!M.chead||!M.rhead)
return false;
for(k=1;k<=m;k++)
M.rhead[k]=NULL;
for(k=1;k<=n;k++)
M.chead[k]=NULL;
printf("请按任意次序输入%d个非零元的行 列 元素值:/n",M.tu);
for(k=0;k<t;k++)/
{
scanf("%d%d%d",&i,&j,&e);
p=(OLink)malloc(sizeof(OLNode));
if(!p)
return false;
p->i=i;
p->j=j;
p->e=e;
if(M.rhead[i]==NULL||M.rhead[i]->j>j)
{
p->right=M.rhead[i];
M.rhead[i]=p;
}
else
{
for(q=M.rhead[i];q->right&&q->right->j<j;q=q->right) //注意为什么是q->right&&q->right->j<j而不是q&&q->j<j
;
p->right=q->right;
q->right=p;
} //以上在巡查在行表中的插入位置
if(M.chead[j]==NULL||M.chead[j]->i>i)
{
p->down=M.chead[j];
M.chead[j]=p;
}
else
{
for(q=M.chead[j];q->down&&q->down->i<i;q=q->down)
;
p->down=q->down;
q->down=p;
}//以上在查询在列表中的插入位置
}
return true;
}
void PrintSMatrix(CrossList M)
{
int j;
OLink p;
printf("%d行%d列%d个非零元素/n",M.mu,M.nu,M.tu);
for(j=1;j<M.mu;j++)
{
p=M.rhead[j];
while(p)
{
cout<<p->i<<"行"<<p->j<<"列的值为"<<p->e<<endl;
p=p->right;
}
}
}
//矩阵M和N相加 得到矩阵M
void AddMatrix(CrossList &M,CrossList &N)
{
int k;
OLNode *p,*q,*r,*s;
if(M.mu!=N.nu||M.nu!=N.nu)
{
printf("两个矩阵不是同类型的,不能相加/n");
return;
}
for(k=1;k<=M.mu;k++)
{
p=M.rhead[k];
q=N.rhead[k];
while( p||q)
{
switch(Compare(p->j,q->j))
{
case -1:
p=p->right;
break;
case 0:
p->e=p->e+q->e;
if(!p->e)
{
for(s=M.rhead[k];s->right&&s->right->j<p->j;s=s->right)
;
s->right=p->right;
}
//如果p->e为0时,应该把此结点断掉
p=p->right;
q=q->right;
break;
case 1:
r=(OLink)malloc(sizeof(OLNode));
r->i=q->i;
r->j=q->j;
r->e=q->e;
if(M.rhead[k]->j>r->j)
{
r->right=M.rhead[k];
M.rhead[k]=r;
}
else
{
for(s=M.rhead[k];s->right&&s->right->j < r->j;s=s->right)
;
r->right=s->right;
s->right=r;
}
//以上实现了行链接
if(M.chead[r->j]->i > r->i)
{
r->down=M.chead[r->j];
M.chead[r->j]=r;
}
else
{
for(s=M.chead[r->j];s->down&&s->down->i <r->i;s=s->down)
;
r->down=s->down;
s->down=r;
}
//以上实现列链接
q=q->right;
}
}
}
}
//矩阵M和N相乘,得到Q
void MultiSMatrix(CrossList M,CrossList N,CrossList &Q)
{
OLNode *p=NULL,*q=NULL;
OLNode *q2=NULL,*q1=NULL;
int e=0;
if(M.nu!=N.mu)
{
printf("不能相乘,错误/n");
return;
}
Q.mu=M.mu;
Q.nu=N.nu;
Q.rhead=(OLink *)malloc((Q.mu+1)*sizeof(OLink)); //指针的指针
Q.chead=(OLink *)malloc((Q.nu+1)*sizeof(OLink));
for(int i=1;i<=Q.mu;i++)
{
for(int j=1;j<=Q.nu;i++)
{
p=M.rhead[i];
q=N.chead[j];
while(p&&q)
{
if(p->j>q->i)
q=q->down;
else if(q->i>p->j)
p=p->right;
else
{
e+=p->e*q->e;
q=q->down;
p=p->right;
}
}
if(e)
{
Q.tu++;
q=(OLink)malloc(sizeof(OLNode));
q->i=i;
q->j=j;
q->e=e;
q->down=NULL;
q->right=NULL;
if(!Q.rhead[i])
Q.rhead[i]=q;
else
{
q1=Q.rhead[i];
while(q1->right)
q1=q1->right;
q1->right=q;
}
if(!Q.chead[j])
Q.chead[j]=q;
else
{
q2=Q.chead[j];
while(q2->down)
q2=q2->down;
q2->down=q;
}
}
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
CrossList A;
InitSMatrix(A);
printf("创建矩阵A:");
CreateSMatrix(A);
PrintSMatrix(A);
AddMatrix(A,A);
printf("/n");
PrintSMatrix(A);
printf("/n");
CrossList Q;
InitSMatrix(Q);
MultiSMatrix(A,A,Q);
PrintSMatrix(Q);
return 0;
}