#include <iostream> #include <malloc.h> #include <stdio.h> using namespace std; typedef struct OLNode { int i,j; int e; struct OLNode *right,*down; }OLNode,*OLink; typedef struct { OLink *rhead,*chead; int mu,nu,tu; }CrossList; int CreateSMatrix_OL(CrossList &M) { int i,j,k,e; OLink p,q,q1; cout<<"请分别输入该矩阵的行数,列数,所含非零元的个数:"<<endl; cin>>M.mu>>M.nu>>M.tu; if(!M.mu||!M.nu||!M.tu||M.mu*M.mu<M.tu) return 0; M.rhead=(OLink *)malloc((M.mu+1)*sizeof(OLink));//默认从第一行和第一列开始 if(!M.rhead) return 0; M.chead=(OLink *)malloc((M.nu+1)*sizeof(OLink)); if(!M.chead) return 0; for(k=1;k<=M.mu;k++) M.rhead[k]=NULL; for(k=1;k<=M.nu;k++) M.chead[k]=NULL; for(k=0;k<M.tu;k++) { cout<<"请输入当前元素在矩阵中的行号,列号,元素值:"<<endl; cin>>i>>j>>e; if(i<1||i>M.mu||j<1||j>M.nu||0==e) {cout<<"该元素输入错误!"; continue;} p=(OLink)malloc(sizeof(OLNode)); p->i=i; p->j=j; p->e=e; //判断横行插入的位置 if(!M.rhead[i]||M.rhead[i]->j>j) { p->right=M.rhead[i]; M.rhead[i]=p; } else { q=M.rhead[i]; q1=q->right; if(!q1) { q->right=p;p->right=NULL;} else { while(q1->j<j) { q=q->right; q1=q1->right; if(!q1) break; } if(q1) { q->right=p; p->right=q1; } else { q->right=p;p->right=NULL;} } } //判断纵行插入的位置 if(!M.chead[j]||M.chead[j]->i>i) { p->down=M.chead[j]; M.chead[j]=p; } else { q=M.chead[j]; q1=q->down; if(!q1) { q->down=p;p->down=NULL;} else { while(q1->i<i) { q=q->down; q1=q1->down; if(!q1) break; } if(q1) { q->down=p; p->down=q1; } else { q->down=p;p->down=NULL;} } } } return 0; } int Display(CrossList M) { int k; OLink p; for(k=1;k<=M.mu;k++) { p=M.rhead[k]; while(p) { cout<<"("<<k<<","<<p->j<<") "<<"e="<<p->e<<endl; p=p->right; } } cout<<endl; return 0; } int Insert(CrossList M,OLink p)//把p所指向的节点插入到十字链表中 { int i,j,e; OLink q,q1; i=p->i; j=p->j; e=p->e; if(i<1||i>M.mu||j<1||j>M.nu||0==e) cout<<"该元素插入错误!"; if(!M.rhead[i]||M.rhead[i]->j>j) { p->right=M.rhead[i]; M.rhead[i]=p; } else { q=M.rhead[i]; q1=q->right; if(!q1) { q->right=p;p->right=NULL;} else { while(q1->j<j) { q=q->right; q1=q1->right; if(!q1) break; } if(q1) { q->right=p; p->right=q1; } else { q->right=p;p->right=NULL;} } } //判断纵行插入的位置 if(!M.chead[j]||M.chead[j]->i>i) { p->down=M.chead[j]; M.chead[j]=p; } else { q=M.chead[j]; q1=q->down; if(!q1) { q->down=p;p->down=NULL;} else { while(q1->i<i) { q=q->down; q1=q1->down; if(!q1) break; } if(q1) { q->down=p; p->down=q1; } else { q->down=p;p->down=NULL;} } } return 0; } int Delete(CrossList M,OLink p)//把p所指向的节点从十字链表中删除 { int i,j; OLink q,q1; i=p->i; j=p->j; q=M.rhead[i]; q1=q->right; if(j==q->j) { M.rhead[i]->right=q->right; free(q); } else { while(q1->j!=j) { q=q->right; q1=q1->right; } q->right=q1->right; free(q1); } return 0; } OLink IsExist(CrossList M,OLink p)//判断p所指向的节点是否存在于M十字链表中 { int i,j; OLink q; i=p->i; j=p->j; q=M.rhead[i]; while(q) { if(j==q->j) return q; else q=q->right; } return 0; } int SMatrix_Add(CrossList &M1,CrossList M2) { int k; OLink p,pr=NULL; if(M1.mu!=M2.mu||M1.nu!=M2.nu) return 0; for(k=1;k<=M2.mu;k++)//按M2逐行进行 { p=M2.rhead[k]; while(p)//每行用指针逐个后移 { pr=IsExist(M1,p); if(!pr) Insert(M1,p);//如果p所指向的节点在M1中不存在,则直接插入M1 else { pr->e+=p->e; if(!pr->e) Delete(M1,pr); } Display(M1); p=p->right; } } return 0; } int main() { CrossList M1,M2; CreateSMatrix_OL(M1); CreateSMatrix_OL(M2); Display(M1); Display(M2); SMatrix_Add(M1,M2); Display(M1); fclose(stdin); return 0; }