**
用十字链表为存储结构实现矩阵相加 B = B + A
#include#include #include typedef struct OLNode//十字链表存储单元 { int row, col; int data; struct OLNode *right, *down; } OLNode, *OLink; typedef struct CrossList//十字链表 { OLink *row_head, *col_head; int m, n, len; } CrossList; void CreatCrossList(CrossList* M, int m, int n, int len)//创建以十字链表为存储结构的稀疏矩阵 { M->m = m, M->n = n, M->len = len;//读入行列数和非零元素个数 M->row_head = (OLink*)malloc(sizeof(OLink) * (m + 1));//给头指针向量分配空间 if(M->row_head == NULL) return;//判断是否为空指针 M->col_head = (OLink*)malloc(sizeof(OLink) * (n + 1)); if(M->col_head == NULL) return; for(int i = 0; i <= m; i++)//初始化头指针向量为空 M->row_head[i] = NULL; for(int i = 0; i <= n; i++) M->col_head[i] = NULL; int i, j, e;//开始读入数据 for(int k = 0; k < M->len; k++) { scanf("%d %d %d", &i, &j, &e); OLink p = (OLink)malloc(sizeof(OLNode));//创建一个结点 if(p == NULL) return; p->row = i, p->col = j, p->data = e;//将数据赋给创建的结点 p->right = p->down =NULL;//初始化指针 //横向分配存储位置 OLink q; if(M->row_head[i] == NULL)//该行头指针为空 M->row_head[i] = p; else if(M->row_head[i]->col > j)//该行第一个结点列数大于该结点 { p->right = M->row_head[i]; M->row_head[i] = p; } else//该行第一个结点列数小于该结点 { for(q = M->row_head[i]; q->right && q->right->col < j; q = q->right);//空循环 p->right = q->right; q->right = p; } //列向分配存储位置(思想同上) if(M->col_head[j] == NULL) M->col_head[j] = p; else if(M->col_head[j]->row > i) { p->down = M->col_head[j]->down; M->col_head[j] = p; } else { for(q = M->col_head[j]; q->down && q->down->row < i; q = q->down); p->down = q->down; q->down = p; } } } void Insert(CrossList *M, OLink q)//单个非零元素插入十字链表矩阵中(借用创建十字链表矩阵的思想,只是多了可能会在相同位置的情况,且若相加后为零,还可能删除结点 { int i = q->row, j = q->col;//i,j存放非零元素的行列数 OLink p; if(M->row_head[i] == NULL)//该行没有元素,直接插入 M->row_head[i] = q; else if(M->row_head[i]->col > j)//该行第一个元素列坐标大于该元素列坐标 { q->right = M->row_head[i]; M->row_head[i] = q; } else if(M->row_head[i]->col == j)//该行第一个元素和该元素在同一个位置 { M->row_head[i]->data = M->row_head[i]->data + q->data; if(M->row_head[i]->data == 0)//相加后等于零,删除结点 M->row_head[i] = M->row_head[i]->right; } else//该行第一个元素列坐标小于该元素列坐标 { for(p = M->row_head[i]; p->right && p->right->col < j; p = p->right);//空循环 if(p->right == NULL)//该行所有元素列坐标都小于该元素 p->right = q; else if(p->right->col > j)//该元素列坐标大小介于该行两个元素之间 { q->right = p->right; p->right = q; } else//该元素列坐标大小等于该行某个个元素(不为第一个元素) { p->right->data = p->right->data + q->data; if(p->right->data == 0)//相加等于零,删除结点 p->right = p->right->right; } } } void AddCrossList(CrossList* A, CrossList* B) { OLink p = (OLNode*)malloc(sizeof(OLNode)); for(int k = 1; k <= A->m; k++) { p = A->row_head[k]; while(p) { OLink q =(OLNode*)malloc(sizeof(OLNode));//重新分配结点,目的是不改变原来的A十字链表矩阵 q->data = p->data; q->row = p->row; q->col = p->col; q->right = q->down = NULL; Insert(B, q);//一行一行逐个逐个插入到B十字链表矩阵中去 p = p->right; } } } void Print(CrossList *M)//打印B的稀疏矩阵(三元组形式) { OLink p = (OLNode*)malloc(sizeof(OLNode)); for(int k = 1; k <= M->len; k++)//一行一行地扫描打印 { p = M->row_head[k]; while(p) { printf("%d %d %dn", p->row, p->col, p->data); p = p->right; } } } int main() { int m, n, len1, len2; scanf("%d %d %d %d", &m, &n, &len1, &len2);//读入矩阵行列数,非零元个数 CrossList *A, *B; A = (CrossList*)malloc(sizeof(CrossList));//创建十字链表矩阵 B = (CrossList*)malloc(sizeof(CrossList)); CreatCrossList(A, m, n, len1); CreatCrossList(B, m, n, len2); AddCrossList(A, B);//矩阵相加 Print(B);//输出相加后的矩阵 return 0; } [题目介绍](https://img-blog.csdnimg.cn/d84c53b2607a4926ade0c2c925659223.png#pic_center) 测试数据: 3 4 3 2 1 1 1 1 3 1 2 2 2 1 2 1 2 2 3 正确输出: 1 1 1 1 2 1 1 3 1 2 2 5
## 西北工业大学数据结构noj



