当前位置: 首页 >> 程序设计 >> 数据结构和算法 >> 稀疏矩阵相加的C程序
 

稀疏矩阵相加的C程序

作者:      来源:http://blog.csdn.net/ningboweimin/     发表时间:2007-04-27     浏览次数:      字号:    

编写两个稀疏矩阵相加(A=A+B)的算法,要求稀疏矩阵用十字链表表示。

#include <stdio.h>
#include <malloc.h>

#define MAX 100

struct matnode      //十字链表结点的定义
{
 int row,col;
 struct matnode *right,*down;
 union  {
  int val;//表结点使用V域
  struct matnode *next;//表头结点使用next域
 }tag;
};
struct matnode *createmat(struct matnode *hmone[MAX])
{
 int m,n,t,s,i,r,c,v;
// struct matnode *l,*p,*q;
 struct matnode *h[100],*l,*p,*q;  //h[]是十字链表每行的表头指针数组
 printf("行数m,列数n,非零元素个数t:");
 //scanf("%d,%d,%d",&m,&n,&t); //输入行、列数,非零元素个数
 scanf("%d,%d,%d",&m,&n,&t);//输入行、列数,非零元素个数
 l=(struct matnode *)malloc(sizeof(struct matnode));
 h[0]=l;//h[]是指针数组,分别指向头节点和行、列表头结点
 l->row=m; //建立十字链表头结点*l
 l->col=n;
 s=m>n ? m:n; //确定表头节点个数 s=max(m,n)
 for(i=1;i<=s;i++)//建立头节点循环链表
 {
  p=(struct matnode *)malloc(sizeof(struct matnode));
  p->row=p->col=0;
  p->down=p->right=p;
  h[i]=p;
  h[i-1]->tag.next=p;  
 }

 //最后一个行、列表头结点指向十字链表头节点
 h[s]->tag.next=h[0];

 for(i=1;i<=t;i++)       //t为非零元素个数
 {
  printf("\t 第%d个元素(行号m,列号n,值v):",i);
  scanf("%d,%d,%d",&r,&c,&v);
  p=(struct matnode *)malloc(sizeof(struct matnode));
  //生成一个非零表结点*p
  p->row=r;
  p->col=c;
  p->tag.val=v;

        //以下是将*p结点插入第r行链表中
  q=h[r]; //取第r行表头结点
  while(q->right!=h[r]&&q->right->col<c)
   q=q->right;//在第r行中找第一个列号大于c的结点*(q->right)
  //找不到时,*q是该行表上的尾结点
  p->right=q->right;
  q->right=p;//*p插在*q之后

  //以下是将结点插入第c列链表中
  q=h[c];//取第c列表头结点
  while(q->down!=h[c]&&q->down->row<r)
   q=q->down;//在第c列中找第一个列号大于c的结点*(q->down)
  //找不到时,*q是该列表上的尾结点
  p->down=q->down;
  q->down=p;//*p插在*q之后
 }
 return(h[0]);
}
void prmat(struct matnode *hm)
{
 struct matnode *p,*q;
 printf("\n 按行表输出矩阵元素:\n");
 printf("row=%d col=%d\n",hm->row,hm->col);
 p=hm->tag.next;
 while(p!=hm)
 {
  q=p->right;
  while(p!=q)
  {
   printf("\t %d,%d,%d\n",q->row,q->col,q->tag.val);
   q=q->right;
  }
  p=p->tag.next;
 }
}

struct matnode *colpred(int i,int j, struct matnode *h[])
//根据i(行号)和j(列号)找出矩阵第i行第j列的非零元素在十字链表中的前驱结点
{
 struct matnode *d;
 d=h[j];
 while(d->down->col!=0 && d->down->row<i)
  d=d->down;
 return (d);
}


//求矩阵相加的算法
struct matnode *addmat(struct matnode *ha,struct matnode *hb,struct matnode *h[])
{
 struct matnode *p,*q,*ca,*cb,*pa,*pb,*qa;
  if(ha->row!=hb->row||ha->col!=hb->col)
  {
   printf("两个矩阵不是同类型的,不能相加!\n");
   return (0);
  }
  else
  {
   ca=ha->tag.next;
   cb=hb->tag.next;
   do
   {
    pa=ca->right;
    pb=cb->right;
    qa=ca;
    while(pb->col!=0)
     if(pa->col<pb->col&&pa->col!=0)
     {
      qa=pa;
      pa=pa->right;
     }
     else
      if(pa->col>pb->col||pa->col==0)
      {
       p=(struct matnode*)malloc(sizeof(struct matnode));
       *p=*pb;
       p->right=pa;
       qa->right=p;
       qa=p;
       q=colpred(p->row,p->col,h);
       p->down=q->down;
       q->down=pa;
       pb=pb->right;
      }
      else
      {
       pa->tag.val+=pb->tag.val;
       if(pa->tag.val==0)
       {
        qa->right=pa->right;
        q=colpred(pa->row,pa->col,h);
        q->down=pa->down;
        free(pa);
       }
       else qa=pa;
       pa=pa->right;
       pb=cb->right;
      }
      ca=ca->tag.next;
      cb=cb->tag.next;
   }while(ca->row==0);
  }
  return (h[0]);
}


void main(void)
{
 struct matnode *hm,*hm1,*hm2;
 struct matnode *h[MAX],*h1[MAX];
 printf("第一个矩阵:\n");
  hm1=createmat(h);
 printf("第二个矩阵:\n");
  hm2=createmat(h1);
 hm=addmat(hm1,hm2,h);
 prmat(hm);
}
 

责任编辑 webmaster

 
 
 
 
 
评论更多>>
 
 
 
发表
 
姓名: QQ:
性别: MSN:
E-mail: 主页:
评分: 1 2 3 4 5
评论内容:
验证码:
  
  • 请遵守《互联网电子公告服务管理规定》及中华人民共和国其他各项有关法律法规。
  • 严禁发表危害国家安全、损害国家利益、破坏民族团结、破坏国家宗教政策、破坏社会稳定、侮辱、诽谤、教唆、淫秽等内容的评论 。
  • 用户需对自己在使用本站服务过程中的行为承担法律责任(直接或间接导致的)。
  • 本站管理员有权保留或删除评论内容。
  • 评论内容只代表网友个人观点,与本网站立场无关。
  •