資料結構13——以十字連結串列為儲存結構實現矩陣相加(嚴5.27)
阿新 • • 發佈:2019-02-06
Description
以十字連結串列為儲存結構,編寫程式,將稀疏矩陣B加到稀疏矩陣A上。
Input
第一行輸入四個正整數,分別為稀疏矩陣A和稀疏矩陣B的行數m、列數n、稀疏矩陣A的非零元素個數t1和稀疏矩陣B的非零元素個數t2。接下來的t1+t2行三元組表示,其中第一個元素表示非零元素所在的行值,第二個元素表示非零元素所在的列值,第三個元素表示非零元素的值。
Output
輸出相加後的矩陣三元組。
- Sample Input
3 4 3 2 1 1 1 1 3 1 2 2 2 1 2 1 2 2 3
- Sample Output
1 1 1 1 2 1 1 3 1 2 2 5
#include<stdio.h> #include<stdlib.h> typedef struct OLNode{ int row,col; int num; struct OLNode *right,*down; }OLNode,*OLink; typedef struct CrossList{ OLink rHead[100],cHead[100]; int ru,cu,tu; }CrossList; CrossList *M; void init(CrossList *M,int cnt){ int x,y,z; OLink r; while(cnt--){ OLink q=(OLink)malloc(sizeof(OLNode)); scanf("%d%d%d",&x,&y,&z); q->row=x;q->col=y;q->num=z; if(M->rHead[x]==NULL||M->rHead[x]->col > y){ q->right=M->rHead[x]; M->rHead[x]=q; M->ru++; } else{ for(r=M->rHead[x];r->right && r->right->col < y;r=r->right); q->right=r->right; r->right=q; M->ru++; }//完成行插入 if(M->cHead[y]==NULL||M->cHead[y]->row > x){ q->down=M->cHead[y]; M->cHead[y]=q; M->cu++; } else{ for(r=M->cHead[y];r->down && r->down->row < x;r=r->down); q->down=r->down; r->down=q; M->cu++; }//完成列插入 } } void add(CrossList *M,int cnt){ OLink l,t,p; int flag,flag1; int i,x,y,z; while(cnt--){ scanf("%d%d%d",&x,&y,&z); OLink r=(OLink)malloc(sizeof(OLNode)); r->row=x; r->col=y; r->num=z; flag=1; flag1=1; if(M->rHead[x] != NULL){ for(l=M->rHead[x];l;l=l->right){ if(l->col == r->col){ l->num+=r->num; if(l->num == 0){//刪除0 if(flag1){ flag1=0; M->rHead[x] = M->rHead[x]->right; } else{ p = M->rHead[x]; while(p->right != l){ p = p->right; } p->right = l->right; } for(t = M->cHead[y];t;t=t->down){ if(t == M->cHead[y]){ M->cHead[y] = t->right; break; } else{ p = M->cHead[y]; while(p->down != l){ p = p->down; } p->down = l->down; break; } } free(l); } flag=0; break; } } } if(flag){ if(M->rHead[x]==NULL){ r->right=M->rHead[x]; M->rHead[x]=r; M->ru++; } else if(M->rHead[x]->col > y){ r->right=M->rHead[x]; M->rHead[x]=r; } else{ for(l=M->rHead[x];l->right && l->right->col < y;l=l->right); r->right=l->right; l->right=r; } if(M->cHead[y]==NULL){ r->down=M->cHead[y]; M->cHead[y]=r; M->cu++; } else if(M->cHead[y]->row > x){ r->down = M->cHead[y]; M->cHead[y]=r; } else{ for(l=M->cHead[y];l->down && l->down->row < x;l=l->down); r->down=l->down; l->down=r; } } } } void output(CrossList *M){ int i; OLink r,t; for(i=1;i<=M->ru;i++){ if(M->rHead[i]){ for(t=M->rHead[i];t;t=t->right){ printf("%d %d %d\n",t->row,t->col,t->num); } } } } int main(){ M=(CrossList *)malloc(sizeof(CrossList)); int m,n,t1,t2,max; scanf("%d%d%d%d",&m,&n,&t1,&t2); int i; M->cu=0;M->ru=0; if(m>n) max=m; else max=n; for(i=1;i<=max;i++){ M->cHead[i]=NULL; M->rHead[i]=NULL; } init(M,t1); add(M,t2); output(M); return 0; }
題解:
首先在初始化時輸入第一個三元組表示的矩陣,接著一一輸入第二個矩陣的三元組。分情況考慮:如果新輸入資料的行列均不為空,所加值為0,則刪去原來的元素;如果行為空,或所在行的第一次元素的列比較大,則插入新元素;如果列為空,或所在列的第一個元素的行比較大,則插入新元素。輸出時逐個掃描不為空的行,再依次輸出每一行的三元組。