//以十字链表存储表示随机稀疏矩阵 #include<stdio.h> #include<conio.h> #include<stdlib.h> typedef struct abc { int row,col; int val; //矩阵的行列下标及非零元 struct abc *right; struct abc *down; //行列链表中非零元的后继链域 }olnode,*olink; typedef struct { olink *row_head; olink *col_head; //行列链表中的头指针,且动态定义头指针的个数 int m,n,t; //矩阵的行数列数及非零元的个数 }crosslist; void outcrosslist(crosslist M) { olink p,q; for(int k=1;k<=M.m;k++) { p=M.row_head[k]; q=p->right; while( q!=M.row_head[k] ) { printf("(%2d,%2d:%3d)",q->row,q->col,q->val); q=q->right; } printf("/n"); } } int insertnode(crosslist M) { char ch; olnode *p,*q,*s; s=(olnode *)malloc(sizeof(olnode)); printf("输入插入元素的坐标及元素值:/n"); scanf("%d%d%d",&s->row,&s->col,&s->val); if( (*s).row>M.m || (*s).col>M.n || (*s).row<1 || (*s).col<1 ) { printf("坐标错误!!/n/n"); return 0; } //修改行链表指针 p=M.row_head[s->row]; q=p->right; if( q!=M.row_head[s->row] ) { while( q!=M.row_head[s->row] && q->col<=s->col ) { if( q->row==s->row && q->col==s->col ) { printf("此坐标位置已存在,是否覆盖当前元素值(Y/N):"); ch=getche(); if( ch=='Y' || ch=='y' ) { q->val=s->val; return 1; } else return 0; } p=q; q=q->right; } } s->right=q; p->right=s; //此种情况是插入空循环链表中, 或插入行链表的某一位置 //修改列链表指针 p=M.col_head[s->col]; q=p->down; if( q!=M.col_head[s->col] ) { while( q!=M.col_head[s->col] && q->row<=s->row ) { p=q; q=q->down; //寻找插入位置 } } s->down=q; p->down=s; //插入结点 return 1; } int deletenode(crosslist M) { int r,c,k=0; olnode *p,*q; printf("输入待删矩阵元素的坐标:/n"); scanf("%d%d",&r,&c); if(r>M.m || c>M.n || r<1 || c<1) { printf("矩阵坐标错误!!/n"); return 0; } p=M.row_head[r]; q=(*p).right; //q=p->right,p指向头结点,q指向首元结点 while( k==0 && q!=M.row_head[r] ) { if( q->row==r && q->col==c ) { p->right=q->right; k=1; } p=q; q=q->right; } if(!k) return 0; //没有待删的元素 p=M.col_head[c]; q=p->down; while( q!=M.col_head[c] ) { if( q->row==r && q->col==c ) { p->down=q->down; free(q); return 1; //成功删除结点 } p=q; q=q->down; } } int main() { crosslist M; int m,n,t,i,j,e; olnode *p,*q; //输入矩阵 printf("输入矩阵的行数、列数及非零元的个数:/n"); scanf("%d%d%d",&m,&n,&t); M.m=m; M.n=n; M.t=t; if(!(M.row_head=(olink *)malloc((M.m+1)*sizeof(olink)))) exit(0); if(!(M.col_head=(olink *)malloc((M.n+1)*sizeof(olink)))) exit(0); //初始化行列链表为带表头结点的循环单链表 for(int h=0;h<m+1;h++) { M.row_head[h]=(olnode *)malloc(sizeof(olnode)); M.row_head[h]->right=M.row_head[h]; } for(int k=0;k<n+1;k++) { M.col_head[k]=(olnode *)malloc(sizeof(olnode)); M.col_head[k]->down=M.col_head[k]; } printf("输入一个三元组,i=0退出循环/n"); for( scanf("%d%d%d",&i,&j,&e); i!=0; scanf("%d%d%d",&i,&j,&e) ) { p=(olnode *)malloc(sizeof(olnode)); //p=new olnode; p->row=i; p->col=j; p->val=e; //生成一个结点 q=M.row_head[p->row]; if( q->right!=M.row_head[p->row] ) while( q->right!=M.row_head[p->row] && q->right->col<p->col ) //行链表中寻找插入结点的位置 q=q->right; p->right=q->right; q->right=p; q=M.col_head[p->col]; if( q->down!=M.col_head[p->col] ) while( q->down!=M.col_head[p->col] && q->down->row<p->row ) //列链表中寻找结点的插入位置 q=q->down; p->down=q->down; q->down=p; } printf("输出矩阵/n/n"); outcrosslist(M); if( insertnode(M) ) { printf("/n/n插入后的十字链表为:/n/n"); outcrosslist(M); } else printf("/n/n没有对十字链表进行修改!/n/n"); if( deletenode(M) ) { printf("删除矩阵元素后的十字链表为:/n/n"); outcrosslist(M); } else printf("没有待删除的元素!!/n/n"); return 0; }