十字链表表示稀疏矩阵的基本操作

 【问题描述】两个相同行数和列数的稀疏矩阵用十字链表实现加法运算

【数据描述】

typedef struct ele {/* 十字链表结点类型*/

  int row, col;

  double val;

  struct ele *right, *down;

}eleNode;

【算法描述】

(1) 若q->j>v->j,则需要在C矩阵的链表中插入一个值为bij的结点,,修改v=v->right。

(2) 如q->j<v->j,则需要在C矩阵的链表中插入一个值为aij的结点,修改q=q->right。

(3) 若q->j = = v->j且q->e + v->e ! = 0,则需要在C矩阵的链表中插入一个值为aij+bij的结点,修改q=q->right,v=v->right。

重复(1)--(3)完成一行的操作。修改p=p->down,u=u->down后,再继续下一行。【C源程序】

#include <stdio.h>

#include <malloc.h>

typedef struct ele {/* 十字链表结点类型*/

int row,col;

int val;

struct ele *right,*down;

}eleNode;

/*建立一个元素全为零的稀疏矩阵的十字链表*/

eleNode *createNullMat(int m,int n)         / * m行n列 */

{eleNode *h,*p;

int k;

h=(eleNode *)malloc(sizeof(eleNode));       /*十字链表头结点 */

h->row=m;h->col=n;h->val=0;                 / * 行数、列数和非零元素个数 */

h->right=(eleNode *)malloc(sizeof(eleNode)*n);

h->down=(eleNode *)malloc(sizeof(eleNode)*m);

for(p=h->down,k=0;k<m;k++,p++){

p->col=1000;                             / * 设矩阵不会超过1000列 */

p->right=p;                             / * 每个行链表是一个环 * /

p->down=k<m-1?p+1:h->down;                / * 使全部行链表头结点构成环*/

}

for(p=h->right,k=0;k<n;k++,p++){

p->row=1000;                             / * 设矩阵不会超过1000行 * /

   p->down = p;                         / * 每个列链表是一个环 * /

   p->right = k<n-1 ? p+1 : h->right;    / *使全部列链表头结点构成环 * /

}

return h;

}

//

int insertNode(eleNode *a ,int row,int col,double val){

/* 在十字链表中插入一个结点*/

eleNode *p,*q,*r,*u,*v;

if(row>=a->row||col>=a->col) return -2;    / * 不合理的行列号 * /

r=(eleNode *)malloc(sizeof(eleNode));

r->row=row;r->col=col;r->val=val;

p=a->down+row;q=p->right;

while(q->col<col){p=q;q=q->right;}

if(q->col==col) return -1;                 / * 该行已有col列元素 * /

u=a->right+col;v=u->down;

while(v->row<row){u=v;v=v->down;}

if(v->row==row) return -1;            / * 该列已有row行元素 * /

p->right = r; r->right = q;             / * 插入到行链中 * /

u->down = r; r->down = v;               / * 插入到列链中 * /

a->val=val;

return 0;                                / * 插入成功 * /

}

 

eleNode *readMat(){

/*输入数据建立十字链表*/

eleNode *h;

int i,j,m,n;

int v;

printf("输入稀疏矩阵的行数和列数");

scanf("%d%d",&m,&n);

h=createNullMat(m,n);

printf("输入有非零元素的行号");

scanf("%d",&i);

while(i>=0)                                / * 逐行输入非零元素 * /

{  printf("输入非零元素的列号");

    scanf("%d",&j);

    while(j>=0)                             / * 输入一行非零元素 * /

    { printf("输入非零元素的值");

    scanf("%d",&v);

    insertNode(h,i,j,v);

   printf("输入当前行下一个非零元素的列号(-1表示当前行一组数据结束)");

    scanf("%d",&j);

    }

printf("输入下一行有非零元素的行号(-1表示输入结束)");

scanf("%d",&i);

}

return h;

}

void showMat(eleNode *a)

{int row,col,i,j;

eleNode *p;

row=a->row;

col=a->col;

for (i=0;i<row;i++)

   { p=a->down+i;

    p=p->right;

    for(j=0;j<col;j++)

    { if(p->row==i&&p->col==j) {printf("%d  ",p->val);p=p->right;}

     else

     printf("0  ");

     }

   printf("/n");

   }

}

eleNode *matAdd(eleNode *a,eleNode *b)

{eleNode *r,*p,*q,*u,*v;

r=createNullMat(a->row,a->col);

p=a->down;u=b->down;

do {                                   / * 逐行相加 * /

q=p->right;v=u->right;

while(q!=p||v!=u)                      / * 两矩阵中有一个一行未结束循环 */

   if(q->col==v->col){                 / * 有相同列的元素 * /

    if(q->val+v->val!=0)                / * 和非零插入 * /

    insertNode(r,q->row,q->col,q->val+v->val);

    q=q->right;v=v->right;

    }

    else if(q->col<v->col){             / * 插入a的元素 * /

    insertNode(r,q->row,q->col,q->val);

    q=q->right;

    }

   else{                                / * 插入b的元素 * /

   insertNode(r,v->row,v->col,v->val);

   v=v->right;

   }

p=p->down;u=u->down;

}while(p!=a->down);

return r;

}



void main()

{ eleNode *a,*b,*c;

   a=readMat();

   printf("a/n");

   showMat(a);

   b=readMat();

   printf("b/n");

   showMat(b);

  c= matAdd(a,b);

  printf("c/n");

  showMat(c);

  }

【测试数据】

输入a 矩阵:  4  0  0  0       输入b矩阵: 0  1  0  1       输出:4  1  0  1

                       0  5  0  9                          0 –5  0  0              0  0  0  9

                       0  0  1  0                          1  0  9  0                 1  0  10 0

输入数据注意事项:

(1)如上面a矩阵,应输入3行4列

(2)若某行有非零元素,则按下列格式(三元组格式)输入:

行号  列号  值  列号  值  …  列号  值  -1,如a矩阵的第0行,应输入0  0  4  -1,最后 的-1表示该行的一组数据输入结束。

(3)按以上格式逐行地输入数据,直到输入的行号的值为-1时,表示稀疏矩阵的全部数据输入结束。

【说明】

从一个结点来看,进行比较、修改指针所需的时间是一个常数;整个运算过程在于对A和B的十字链表逐行扫描,其循环次数主要取决于A和B矩阵中非零元素的个数ta和tb;由此算法的时间复杂度为O(ta+tb)。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值