用三元组和十字链表实现稀疏矩阵的装置,相加和相乘_姚伯祥_新浪博客

这是自己{dy}次编那么长的代码,虽然一些代码是抄的,不过还是有一点成就感的。哈哈。

#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100
int num[100];
typedef struct OLNode{
int i,j;
int e;
struct OLNode *right,*down;
}OLNode,*OLink;

typedef struct {
int mu,nu,tu;
OLink *rhead,*chead;
}CrossList;

typedef struct{
int i,j;
int e;
}Triple;
typedef struct{
Triple data[MAXSIZE];
 int    rpos[MAXSIZE + 1];  
int nu,mu,tu;
}TSMatrix;

int CreateSMatix_OL(CrossList &M){
 int i,j,e;
 OLink q;
    OLink p;
printf("请输入稀疏矩阵的行数,列数,非零元素的个数");
scanf("%d%d%d",&M.mu,&M.nu,&M.tu);
M.rhead=(OLink *)malloc((M.mu+1)*sizeof(OLNode));
M.chead=(OLink *)malloc((M.nu+1)*sizeof(OLNode));

for( i=1;i<=M.mu;i++)M.rhead[i]=NULL;
for( i=1;i<=M.nu;i++)M.chead[i]=NULL;
printf("请输入稀疏矩阵,如果行为0,则退出\n");
scanf("%d%d%d",&i,&j,&e);
while(i!=0){
p=(OLink)malloc(sizeof(OLNode));
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{
 q=M.rhead[i];
 while(q->right&&q->right->j<j)q=q->right;
 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{
q=M.chead[j];
while(q->down&&q->down->i<i)q=q->down;
p->down=q->down;
q->down=p;
}
scanf("%d%d%d",&i,&j,&e);
}
return 1;
}//创建十字链表

void CreateSMatrix(TSMatrix &M){
int h,r;
int i,t;
int k=1;
printf("please input the Matri");
scanf("%d",&M.data[k].i);
scanf("%d",&M.data[k].j);
scanf("%d",&M.data[k].e);
h=M.data[k].i;
r=M.data[k].j;
while(M.data[k].i!=-1){k++;
scanf("%d",&M.data[k].i);
scanf("%d",&M.data[k].j);
scanf("%d",&M.data[k].e);
h=h>M.data[k].i?h:M.data[k].i;
r=r>M.data[k].j?r:M.data[k].j;
}
M.tu=--k;
M.mu=h;
M.nu=r;
int num[100];
 if(M.tu)
       {
            for(i = 1; i <= M.mu; i++) num[i] = 0;//初始化
            for(t = 1; t <= M.tu; t++) ++num[M.data[t].i];//求M中每一行含非零元素个数
            //求rpos
            M.rpos[1] = 1;
            for(i = 2; i <= M.mu; i++) M.rpos[i] = M.rpos[i-1] + num[i-1];
      
}//三元组

void TransposeSMatrix(TSMatrix M,TSMatrix &T){
T.nu=M.mu;
T.mu=M.nu;
T.tu=M.tu;
int q=1;
for(int col=1;col<=M.nu;col++)
for(int p=1;p<=M.tu;p++)
if(M.data[p].j==col){
T.data[q].i=M.data[p].j;
T.data[q].j=M.data[p].i;
T.data[q].e=M.data[p].e;
q++;
}
}//三元组装置

int Compare(int a1,int b1,int a2,int b2){
if(a1>a2)return 1;
else if(a1<a2)return -1;
else if(b1>b2)return 1;
if(b1<b2)return -1;
else return 0;
}

void AddTMatix(TSMatrix M,TSMatrix T,TSMatrix &S){
 S.mu=M.mu>T.mu?M.mu:T.mu;
 S.nu=M.nu>T.nu?M.nu:T.nu;
 S.tu=0;
 int ce;
 int q=1;int mcount=1,tcount=1;
 while(mcount<=M.tu&&tcount<=T.tu){
 switch(Compare(M.data[mcount].i,M.data[mcount].j,T.data[tcount].i,T.data[tcount].j))
 {case -1: S.data[q].e=M.data[mcount].e;
  S.data[q].i=M.data[mcount].i;
  S.data[q].j=M.data[mcount].j;
  q++;
  mcount++; 
  break;

 case 1: S.data[q].e=T.data[tcount].e;
  S.data[q].i=T.data[tcount].i;
  S.data[q].j=T.data[tcount].j;
  q++;
  tcount++; 
  break;
 case 0: ce=M.data[mcount].e+T.data[tcount].e;
  if(ce){   S.data[q].e=ce;
  S.data[q].i=M.data[mcount].i;
  S.data[q].j=M.data[mcount].j;
  q++;
  mcount++;
  tcount++;}
  else {mcount++;
  tcount++;}
  break;
}}
 while(mcount<=M.tu){
S.data[q].e=M.data[mcount].e;
S.data[q].i=M.data[mcount].i;
S.data[q].j=M.data[mcount].j;
q++;
mcount++; }
 while(tcount<=M.tu){
         S.data[q].e=T.data[tcount].e;
   S.data[q].i=T.data[tcount].i;
   S.data[q].j=T.data[tcount].j;
    q++;
   tcount++; 
 }
 S.tu=q-1;
}//三元组相加

int  MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q)
{
       int arow, brow, ccol, i, t, ctemp[100], p, q, tp;
     
       if(M.nu != N.mu) return 0;
 
       Q.mu = M.mu, Q.nu = N.nu, Q.tu = 0;
 
       if(M.tu * N.tu != 0)
       {
            for(arow = 1; arow <= M.mu; ++arow)
            {
                 for(i = 0; i <= N.nu; ++i) ctemp[i] = 0;
                 Q.rpos[arow] = Q.tu + 1;
                 if(arow < M.mu) tp = M.rpos[arow + 1];
                 else tp = M.tu +1;
                 for(p = M.rpos[arow]; p < tp; ++p)
                 {
                      brow = M.data[p].j;        
                      if(brow < N.mu) t = N.rpos[brow+1];
                      else t = N.tu + 1;
                      for(q = N.rpos[brow]; q < t; ++q)
                      {
                           ccol = N.data[q].j;     
                           ctemp[ccol] += M.data[p].e * N.data[q].e;
                      }
                 }
                 for(ccol = 1; ccol <= Q.nu; ++ccol) 
                 {
                      if(ctemp[ccol])
                      {
                           if(++(Q.tu) > MAXSIZE) return 1;
                           Q.data[Q.tu].i = arow, Q.data[Q.tu].j = ccol, Q.data[Q.tu].e = ctemp[ccol];         
                       
                 }
            
       }
       return 1;
}//三元组相乘


void ShowTMatrix(TSMatrix M){
for(int col=1;col<=M.mu;col++)
for(int p=1;p<=M.tu;p++)
if(M.data[p].i==col)printf("%4d %4d %4d\n",M.data[p].i,M.data[p].j,M.data[p].e);
}//三元组显示

int SMatrix_ADD(CrossList *A,CrossList *B){
OLNode *pa,*pb,*pre,*p,*cp[100];
int i,j,t;
t=A->tu+B->tu;
for(j=1;j<=A->nu;j++)cp[j]=A->chead[j];
for(i=1;i<=A->mu;i++){
pa=A->rhead[i];
pb=B->rhead[i];
pre=NULL;
while(pb){
 
 if(pa==NULL||pa->j>pb->j){
p=(OLink)malloc(sizeof(OLNode));
if(!pre)A->rhead[i]=p;
else pre->right=p;
p->right=pa;
pre=p;
p->i=i;p->j=pb->j;p->e=pb->e;

if(!A->chead[p->j]){
A->chead[p->j]=cp[p->j]=p;
p->down=NULL;
}
else{
cp[p->j]->down=p;
cp[p->j]=p;
}
pb=pb->right;
}
else if(pa->j<pb->j){pre=pa;
  pa=pa->right;}
 else if(pa->e+pb->e){
  t--;
  pa->e+=pb->e;
  pre=pa;
  pa=pa->right;
    pb=pb->right;}
 else {    t=t-2;
   if(!pre)A->rhead[i]=pa->right;
   else pre->right=pa->right;
   p=pa;pa=pa->right;
   if(A->chead[p->j]==p)A->chead[p->j]=cp[p->j]=p->down;
   else cp[p->j]->down=p->down;
   free(p);
   pb=pb->right;
}
}
}
A->mu=A->mu>B->mu?A->mu:B->mu;
A->nu=A->nu>B->nu?A->nu:B->nu;
return 1;
}//十字链表相加


int ShowMAtrix(CrossList *A){
 int col;
    OLink p;

 for(col=1;col<=A->mu;col++)if(A->rhead[col]){p=A->rhead[col];
 while(p){printf("%3d%3d%3d\n",p->i,p->j,p->e);p=p->right;}
 }
 return 1;
}//十字链表显示

int MultSMatrix_OL(CrossList M, CrossList N, CrossList &Q)
{
       int i, j, e;            //中间变量
       OLink p0, q0, p, pl, pla;        //中间变量
       //检查稀疏矩阵M的列数和N的行数是否对应相等
       if(M.nu != N.mu)
       {
          printf (  "稀疏矩阵A的列数和B的行数不相等,不能相乘。\n" );
            return 0;  
       }
      
       Q.mu = M.mu, Q.nu = N.nu, Q.tu = 0;
       if(!(Q.rhead = (OLink *)malloc((Q.mu + 1) * sizeof(OLink)))) exit(-2);
       if(!(Q.chead = (OLink *)malloc((Q.nu + 1) * sizeof(OLink)))) exit(-2);
       for(i = 1; i <= Q.mu; i++) Q.rhead[i] = NULL;
       for(i = 1; i <= Q.nu; i++) Q.chead[i] = NULL;
       //相乘
       for(i =1; i <= Q.mu; i++)
            for(j = 1; j <= Q.nu; j++)
            {
                  p0 = M.rhead[i], q0 = N.chead[j], e = 0;
                  while(p0&&q0)//M第i行和N第j列有元素
                  {
                       if( p0->j > q0->i) q0 = q0->down;     //M的列大于N的行,则N的列指针后移
                       else if(p0->j < q0->i) p0 = p0->right;//M的列小于N的行,则M的行指针右移
                       else {//M的行等于N的列
                            e += p0->e * q0->e;           //乘积累加
                            q0 = q0->down, p0 = p0->right;//移动指针
                       }
                  }
                  if(e)//乘积不为0
                  {
                       if(!(p = (OLink)malloc(sizeof(OLNode)))) exit(-2);
                       Q.tu++;//非零元素增加
                       p->i = i, p->j = j, p->e = e, p->right = NULL, p->down = NULL;//赋值,指针后移
                       //将p插入十字链表
                       //行插入
                       if(Q.rhead[i] == NULL)                  //若p为该行的第1个结点
                            Q.rhead[i] = pl = p;               //p插在该行的表头且pl指向p(该行的{zh1}一个结点)
                       else pl->right = p, pl = p;             //插在pl所指结点之后,pl右移
                       //列插入
                       if(Q.chead[j] == NULL)                  //若p为该列的{dy}个结点
                            Q.chead[j] = p;                    //该列的表头指向p
                       else {//插在列表尾
                            pla = Q.chead[j];//pla指向j行的第1个结点
                            while(pla->down) pla = pla->down;//pla指向j行{zh1}一个结点
                            pla->down = p; 
                       }
                  }
            }
       return 1;
}//十字链表相乘

 

void   TurnSMatrix_OL(CrossList &M){
int col,row;
OLink p,q;
for(col=1;col<=M.mu;col++)
q=p=M.rhead[col];
while(q){
row=p->i;
p->i=p->j;
p->j=row;
q=p->right;
p->right=p->down;
p->down=q;
}
}
}//十字链表转置

int DestroySMatrix_OL(CrossList &M)
{
       int i;//中间变量
       OLink p, q;//中间变量
      
       if(!M.rhead || !M.chead) return 1;//M不存在
       else {//M存在
            if(M.chead)//所有列链表头指针置为空
                 for(i = 1; i <= M.nu; i++)
                      M.chead[i] = NULL;               
            
            if(M.rhead)//按行释放节点
                 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);
            //返回
            return 1;
       }
}//十字链表销毁


void main(){
int n,i;
TSMatrix M,T,S;
CrossList MM,TT,SS;

printf("请你选择创建稀疏矩阵的方法   1:用三元组创建稀疏矩阵 。 2:用十字建表创建稀疏矩阵。3:退出");
scanf("%d",&n);
switch(n){
case 1:
CreateSMatrix(M);
printf("已经选择三元组创建稀疏矩阵,请选择操作 1:稀疏矩阵转置   2:稀疏矩阵相加   3:稀疏矩阵相乘 4:退出");
scanf("%d",&i);
switch(i){
case 1:TransposeSMatrix(M,T);
ShowTMatrix(T);
break;
case 2:printf("请你输入另一个稀疏矩阵:");
 CreateSMatrix(T);
 AddTMatix(M,T,S);
 ShowTMatrix(S);
 break;
case 3:printf("请你输入另一个稀疏矩阵:");
 CreateSMatrix(T);
 MultSMatrix(M,T,S);
     ShowTMatrix(S);
     break;
case 4:exit(0);};break;
case 2:{CreateSMatix_OL(MM);
    printf("已经选择十字链表创建稀疏矩阵,请选择操作 1:稀疏矩阵转置   2:稀疏矩阵相加   3:稀疏矩阵相乘 4:退出");
scanf("%d",&i);
switch(i){
case 1:
   TurnSMatrix_OL(MM);
   ShowMAtrix(&MM);
   break;
case 2:
 printf("请你输入另一个稀疏矩阵:");
 CreateSMatix_OL(TT);
  SMatrix_ADD(&MM,&TT);
  ShowMAtrix(&MM);break;
case 3:printf("请你输入另一个稀疏矩阵:");
 CreateSMatix_OL(TT);
 MultSMatrix_OL(MM,TT,SS);
  ShowMAtrix(&SS);break;
case 4:exit(0);
   
 }};break;
case 3:exit(0);
default :printf("erorr");
}

}

已投稿到:
郑重声明:资讯 【用三元组和十字链表实现稀疏矩阵的装置,相加和相乘_姚伯祥_新浪博客】由 发布,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
—— 相关资讯 ——