十字链表稀疏矩阵基本运算(C语言版)

矩阵的基本运算包括加法乘法和转置

代码实现部分

头文件部分

  1. 稀疏矩阵加法
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;
		}
	}
}
  1. 稀疏矩阵乘法
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;
}
  1. 稀疏矩阵转置
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;
			}

		}
	}
}
  1. 完整头文件
#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;
}

运行结果

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值