矩阵的基本运算包括加法乘法和转置
代码实现部分
头文件部分
- 稀疏矩阵加法
Status AddSMartix(CrossList M, CrossList N, CrossList* Q)
{
int i, k;
OLNode* pm, * pn, * r, * l, * p;
//pm,pn分别指向十字链表的行列指针,r用来保存p,l是寻找插入位置指针,p为插入Q结点
r = NULL;
if (M.mu != N.mu || M.nu != N.nu)
{
printf("不能相加\n");
return ERROR;
}
Q->mu = M.mu;
Q->nu = M.nu;
Q->tu = 0;
Q->rhead = (OLink*)malloc((M.mu + 1)*sizeof(OLink));
Q->chead = (OLink*)malloc((M.nu + 1)*sizeof(OLink));
if (!Q->rhead || !Q->chead)
{
printf("分配内存失败\n");
return ERROR;
}
//初始化行列头指针为空
for (k = 0; k <= M.mu; k++)
Q->rhead[k] = NULL;
for (k = 0; k <= M.nu; k++)
Q->chead[k] = NULL;
//开始遍历
for (i = 1; i <= M.mu; i++)
{
pm = M.rhead[i];
pn = N.rhead[i];
while (pm && pn)
{
if (pm->j == pn->j && pm->e + pn->e == 0)
{
pm = pm->right;
pn = pn->right;
continue;
}
p = (OLink)malloc(sizeof(OLNode));
if (!p)
{
printf("内存分配失败\n");
return ERROR;
}
if (pm->j < pn->j)
{
p->i = pm->i;
p->j = pm->j;
p->e = pm->e;
pm = pm->right;
}
else if (pm->j > pn->j)
{
p->j = pn->j;
p->i = pn->i;
p->e = pn->e;
pn = pn->right;
}
else
{
p->i = pm->i;
p->j = pm->j;
p->e = pm->e + pn->e;
pm = pm->right;
pn = pn->right;
}
p->right = p->down = NULL;
Q->tu++;
if (Q->rhead[p->i] == NULL)
Q->rhead[p->i] = p;
else
r->right = p;
r = p;
if (Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i)
{
r->down = Q->chead[p->j];
Q->chead[p->j] = r;
}
else
{
for (l = Q->chead[p->j]; l->down && l->down->i < p->i; l = l->down);
r->down = l->down;
l->down = r;
}
}
while (pm)
{
p = (OLink)malloc(sizeof(OLNode));
if (!p)
{
printf("内存分配失败\n");
exit(EXIT_FAILURE);
}
p->i = pm->i;
p->j = pm->j;
p->e = pm->e;
p->right = p->down = NULL;
Q->tu++;
if (Q->rhead[p->i] == NULL)
Q->rhead[p->i] = p;
else
r->right = p;
r = p;
if (Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i)
{
r->down = Q->chead[p->j];
Q->chead[p->j] = r;
}
else
{
for (l = Q->chead[p->j]; l->down && l->down->i < p->i; l = l->down);
r->down = l->down;
l->down = r;
}
pm = pm->right;
}
while (pn)
{
p = (OLink)malloc(sizeof(OLNode));
if (!p)
{
printf("内存分配失败\n");
exit(EXIT_FAILURE);
}
p->i = pn->i;
p->j = pn->j;
p->e = pn->e;
p->right = p->down = NULL;
Q->tu++;
if (Q->rhead[p->i] == NULL)
Q->rhead[p->i] = p;
else
r->right = p;
r = p;
if (Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i)
{
r->down = Q->chead[p->j];
Q->chead[p->j] = r;
}
else
{
for (l = Q->chead[p->j]; l->down && l->down->i < p->i; l = l->down);
r->down = l->down;
l->down = r;
}
pn = pn->right;
}
}
}
- 稀疏矩阵乘法
Status MultSMartix(CrossList M, CrossList N, CrossList* Q)
{
int m, n, i;
ElemType e; //记录两矩阵行列相乘的值
OLNode* pm, * pn, * p, * r, * l;
r = NULL;
if (M.nu != N.mu)
{
printf("不能相乘\n");
return ERROR;
}
Q->mu = M.mu;
Q->nu = N.nu;
Q->tu = 0;
Q->rhead = (OLink*)malloc((M.mu + 1) * sizeof(OLink));
Q->chead = (OLink*)malloc((N.nu + 1) * sizeof(OLink));
if (!Q->chead || !Q->rhead)
{
printf("分配失败\n");
exit(EXIT_FAILURE);
}
for (i = 0; i <= M.mu + 1; i++)
Q->rhead[i] = NULL;
for (i = 0; i <= N.nu + 1; i++)
Q->chead[i] = NULL;
if (M.tu * N.tu)
{
for (m = 1; m <= M.mu; m++)
{
for (n = 1; n <= N.nu; n++)
{
pm = M.rhead[m];
pn = N.chead[n];
e = 0;
while (pm && pn)
{
if (pm->j < pn->i)
pm = pm->right;
else if (pm->j > pn->i)
pn = pn->down;
else
{
e += pm->e * pn->e;
printf("%d\n", e);
pm = pm->right;
pn = pn->down;
}
}
if (e) //累加完值不为空创建节点插入新矩阵Q中
{
p = (OLink)malloc(sizeof(OLNode));
if (!p)
exit(EXIT_FAILURE);
p->i = M.rhead[m]->i;
p->j = M.chead[n]->j;
p->e = e;
p->right = p->down = NULL;
Q->tu++;
if (Q->rhead[p->i] == NULL)
Q->rhead[p->i] = p;
else
r->right = p;
r = p;
if (Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i)
{
r->down = Q->chead[p->j];
Q->chead[p->j] = r;
}
else
{
for (l = Q->chead[p->j]; l->down && l->down->i < p->i; l = l->down);
r->down = l->down;
l->down = r;
}
}
}
}
}
return OK;
}
- 稀疏矩阵转置
void TransposeSMatrix(CrossList M, CrossList* T)
{
int i;
OLNode* p, * q, * l, * r;
r = NULL;
T->mu = M.nu;
T->nu = M.mu;
T->tu = M.tu;
T->rhead = (OLink*)malloc((T->mu + 1) * sizeof(OLink));
T->chead = (OLink*)malloc((T->nu + 1) * sizeof(OLink));
if (!T->rhead || !T->chead)
exit(EXIT_FAILURE);
for (i = 0; i <= T->mu; i++)
T->rhead[i] = NULL;
for (i = 0; i <= T->nu; i++)
T->chead[i] = NULL;
if (M.tu)
{
for (i = 1; i <= M.nu; i++) //遍历原矩阵的列成为新矩阵的行
{
q = M.chead[i];
if (!q)
continue;
while (q)
{
p = (OLink)malloc(sizeof(OLNode));
if (!p)
exit(EXIT_FAILURE);
p->i = q->j;
p->j = q->i;
p->e = q->e;
p->right = p->down = NULL;
if (T->rhead[p->i] == NULL)
T->rhead[p->i] = p;
else
r->right = p;
r = p;
if (T->chead[p->j] == NULL || T->chead[p->j]->i > p->i)
{
r->down = T->chead[p->j];
T->chead[p->j] = r;
}
else
{
for (l = T->chead[p->j]; l->down && l->down->i < p->i; l = l->down);
r->down = l->down;
l->down = r;
}
q = q->down;
}
}
}
}
- 完整头文件
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ERROR 1;
#define OK 0;
typedef int Status;
typedef int ElemType;
typedef struct OLNode {
int i, j; //该非0元所在行列
ElemType e; //该非0元元素值
struct OLNode* down, * right; //该非0元所在行列的后继链域
}OLNode, * OLink; //十字链表结构
typedef struct {
OLink* rhead, * chead; //行链表头指针,列链表头指针
int mu, nu, tu; //矩阵的行列与非0元个数
}CrossList;
//稀疏矩阵的加法
Status AddSMartix(CrossList M, CrossList N, CrossList* Q)
{
int i, k;
OLNode* pm, * pn, * r, * l, * p;
//pm,pn分别指向十字链表的行列指针,r用来保存p,l是寻找插入位置指针,p为插入Q结点
r = NULL;
if (M.mu != N.mu || M.nu != N.nu)
{
printf("不能相加\n");
return ERROR;
}
Q->mu = M.mu;
Q->nu = M.nu;
Q->tu = 0;
Q->rhead = (OLink*)malloc((M.mu + 1)*sizeof(OLink));
Q->chead = (OLink*)malloc((M.nu + 1)*sizeof(OLink));
if (!Q->rhead || !Q->chead)
{
printf("分配内存失败\n");
return ERROR;
}
//初始化行列头指针为空
for (k = 0; k <= M.mu; k++)
Q->rhead[k] = NULL;
for (k = 0; k <= M.nu; k++)
Q->chead[k] = NULL;
//开始遍历
for (i = 1; i <= M.mu; i++)
{
pm = M.rhead[i];
pn = N.rhead[i];
while (pm && pn)
{
if (pm->j == pn->j && pm->e + pn->e == 0)
{
pm = pm->right;
pn = pn->right;
continue;
}
p = (OLink)malloc(sizeof(OLNode));
if (!p)
{
printf("内存分配失败\n");
return ERROR;
}
if (pm->j < pn->j)
{
p->i = pm->i;
p->j = pm->j;
p->e = pm->e;
pm = pm->right;
}
else if (pm->j > pn->j)
{
p->j = pn->j;
p->i = pn->i;
p->e = pn->e;
pn = pn->right;
}
else
{
p->i = pm->i;
p->j = pm->j;
p->e = pm->e + pn->e;
pm = pm->right;
pn = pn->right;
}
p->right = p->down = NULL;
Q->tu++;
if (Q->rhead[p->i] == NULL)
Q->rhead[p->i] = p;
else
r->right = p;
r = p;
if (Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i)
{
r->down = Q->chead[p->j];
Q->chead[p->j] = r;
}
else
{
for (l = Q->chead[p->j]; l->down && l->down->i < p->i; l = l->down);
r->down = l->down;
l->down = r;
}
}
while (pm)
{
p = (OLink)malloc(sizeof(OLNode));
if (!p)
{
printf("内存分配失败\n");
exit(EXIT_FAILURE);
}
p->i = pm->i;
p->j = pm->j;
p->e = pm->e;
p->right = p->down = NULL;
Q->tu++;
if (Q->rhead[p->i] == NULL)
Q->rhead[p->i] = p;
else
r->right = p;
r = p;
if (Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i)
{
r->down = Q->chead[p->j];
Q->chead[p->j] = r;
}
else
{
for (l = Q->chead[p->j]; l->down && l->down->i < p->i; l = l->down);
r->down = l->down;
l->down = r;
}
pm = pm->right;
}
while (pn)
{
p = (OLink)malloc(sizeof(OLNode));
if (!p)
{
printf("内存分配失败\n");
exit(EXIT_FAILURE);
}
p->i = pn->i;
p->j = pn->j;
p->e = pn->e;
p->right = p->down = NULL;
Q->tu++;
if (Q->rhead[p->i] == NULL)
Q->rhead[p->i] = p;
else
r->right = p;
r = p;
if (Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i)
{
r->down = Q->chead[p->j];
Q->chead[p->j] = r;
}
else
{
for (l = Q->chead[p->j]; l->down && l->down->i < p->i; l = l->down);
r->down = l->down;
l->down = r;
}
pn = pn->right;
}
}
}
//稀疏矩阵的乘法
Status MultSMartix(CrossList M, CrossList N, CrossList* Q)
{
int m, n, i;
ElemType e; //记录两矩阵行列相乘的值
OLNode* pm, * pn, * p, * r, * l;
r = NULL;
if (M.nu != N.mu)
{
printf("不能相乘\n");
return ERROR;
}
Q->mu = M.mu;
Q->nu = N.nu;
Q->tu = 0;
Q->rhead = (OLink*)malloc((M.mu + 1) * sizeof(OLink));
Q->chead = (OLink*)malloc((N.nu + 1) * sizeof(OLink));
if (!Q->chead || !Q->rhead)
{
printf("分配失败\n");
exit(EXIT_FAILURE);
}
for (i = 0; i <= M.mu + 1; i++)
Q->rhead[i] = NULL;
for (i = 0; i <= N.nu + 1; i++)
Q->chead[i] = NULL;
if (M.tu * N.tu)
{
for (m = 1; m <= M.mu; m++)
{
for (n = 1; n <= N.nu; n++)
{
pm = M.rhead[m];
pn = N.chead[n];
e = 0;
while (pm && pn)
{
if (pm->j < pn->i)
pm = pm->right;
else if (pm->j > pn->i)
pn = pn->down;
else
{
e += pm->e * pn->e;
printf("%d\n", e);
pm = pm->right;
pn = pn->down;
}
}
if (e) //累加完值不为空创建节点插入新矩阵Q中
{
p = (OLink)malloc(sizeof(OLNode));
if (!p)
exit(EXIT_FAILURE);
p->i = M.rhead[m]->i;
p->j = M.chead[n]->j;
p->e = e;
p->right = p->down = NULL;
Q->tu++;
if (Q->rhead[p->i] == NULL)
Q->rhead[p->i] = p;
else
r->right = p;
r = p;
if (Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i)
{
r->down = Q->chead[p->j];
Q->chead[p->j] = r;
}
else
{
for (l = Q->chead[p->j]; l->down && l->down->i < p->i; l = l->down);
r->down = l->down;
l->down = r;
}
}
}
}
}
return OK;
}
//稀疏矩阵的转置
void TransposeSMatrix(CrossList M, CrossList* T)
{
int i;
OLNode* p, * q, * l, * r;
r = NULL;
T->mu = M.nu;
T->nu = M.mu;
T->tu = M.tu;
T->rhead = (OLink*)malloc((T->mu + 1) * sizeof(OLink));
T->chead = (OLink*)malloc((T->nu + 1) * sizeof(OLink));
if (!T->rhead || !T->chead)
exit(EXIT_FAILURE);
for (i = 0; i <= T->mu; i++)
T->rhead[i] = NULL;
for (i = 0; i <= T->nu; i++)
T->chead[i] = NULL;
if (M.tu)
{
for (i = 1; i <= M.nu; i++) //遍历原矩阵的列成为新矩阵的行
{
q = M.chead[i];
if (!q)
continue;
while (q)
{
p = (OLink)malloc(sizeof(OLNode));
if (!p)
exit(EXIT_FAILURE);
p->i = q->j;
p->j = q->i;
p->e = q->e;
p->right = p->down = NULL;
if (T->rhead[p->i] == NULL)
T->rhead[p->i] = p;
else
r->right = p;
r = p;
if (T->chead[p->j] == NULL || T->chead[p->j]->i > p->i)
{
r->down = T->chead[p->j];
T->chead[p->j] = r;
}
else
{
for (l = T->chead[p->j]; l->down && l->down->i < p->i; l = l->down);
r->down = l->down;
l->down = r;
}
q = q->down;
}
}
}
}
函数测试部分
#include "CrossList.h"
int main()
{
printf("测试函数AddSMartix\n");
{
CrossList M, N, Q;
printf("请输入两相加矩阵\n");
InitSmrix_OL(&M);
CreatSMarix_OL(&M);
InitSmrix_OL(&N);
CreatSMarix_OL(&N);
InitSmrix_OL(&Q);
AddSMartix(M, N, &Q);
printf("两相加矩阵为\n");
PrintSMartix(M);
PrintSMartix(N);
printf("结果矩阵为\n");
PrintSMartix(Q);
}
printf("测试函数MultSMartix\n");
{
CrossList M, N, Q;
printf("请输入两相乘矩阵\n");
InitSmrix_OL(&M);
CreatSMarix_OL(&M);
InitSmrix_OL(&N);
CreatSMarix_OL(&N);
InitSmrix_OL(&Q);
MultSMartix(M, N, &Q);
printf("结果矩阵为\n");
PrintSMartix(Q);
}
printf("测试函数TransposeSMatrix\n");
{
CrossList M, T;
printf("创建稀疏矩阵\n");
InitSmrix_OL(&M);
CreatSMarix_OL(&M);
TransposeSMatrix(M, &T);
printf("转置前为\n");
PrintSMartix(M);
printf("转置后为\n");
PrintSMartix(T);
}
return 0;
}
运行结果