1. 程式人生 > >資料結構13——以十字連結串列為儲存結構實現矩陣相加(嚴5.27)

資料結構13——以十字連結串列為儲存結構實現矩陣相加(嚴5.27)

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,則刪去原來的元素;如果行為空,或所在行的第一次元素的列比較大,則插入新元素;如果列為空,或所在列的第一個元素的行比較大,則插入新元素。輸出時逐個掃描不為空的行,再依次輸出每一行的三元組。