稀疏矩阵的行逻辑连接顺序表实现

       下面的程序搞了我半天……

        一点遗憾是: 加法运算中rpos数组成了累赘。rpos的计算无法镶嵌到加法运算过程中(即大循环里面),尝试了多种方法亦无果(大多时间就浪费在这)。最后只能单独计算。C创建动态数组比较麻烦,所以定义中间数组时没有用动态数组,只能用行列数的最大值MAXRC作为数组元素个数。纯C实现,如果是C++,可重载运算符。

        还有,那啥,Visual Assist X实在是太TMD方便了……

//SMatrix.h
#define ERROR	0
#define OK	1
#define MAXRC	100		//the maximum of rows and col
#define MAXSIZE	200		//the maximum of nonzero elements 
					
typedef int Status;
typedef int ElemType;

typedef struct 
{
	int		i,j;
	ElemType	e;
}Triple;
typedef struct  
{
	Triple	data[MAXSIZE + 1];	//nonzero elements table
	int	rpos[MAXRC + 1];	//index of first nonzero element in each row
	int	mu,nu,tu;		//row-number,col-number,nonzero-number
}RLSMatrix;

Status CreateSMatrix(RLSMatrix *M);
Status PrintSMatrix1(RLSMatrix M);
Status PrintSMatrix2(RLSMatrix M);
Status CopySMatrix(RLSMatrix M, RLSMatrix *T);
Status AddSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix *Q);
Status MultSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix *Q);
Status TransposeSMatrix(RLSMatrix M, RLSMatrix *T);

//SMatrix.c
#include "SMatrix.h"
#include <stdio.h>

Status CreateSMatrix(RLSMatrix *M)
{
	Triple t;
	int i,j;	

	M->tu = 0;
	printf("Enter the number of row: ");scanf_s("%d",&M->mu);
	printf("Enter the number of col: ");scanf_s("%d",&M->nu);

	printf("Enter the nonzero elements:\n");
	for(i = 1; i<= M->mu; i++)M->rpos[i] = 0;
	for(i = 1; i<= M->mu; i++)
	{
		printf("Row %d(Enter zero to finish inputting this row):\n",i);
		t.i = i;
		for(j = 1; j<= M->nu; j++)
		{
			printf("Col: ");scanf_s("%d",&t.j);
			if(t.j <= 0)	
			{	//整行为0的情况
				if(M->rpos[i] == 0) M->rpos[i] = M->tu + 1; 
				break;
			}
			else j = t.j;

			if(M->rpos[i] == 0)M->rpos[i] = M->tu + 1;

			printf("Element: ");scanf_s("%d",&t.e);
			M->data[++M->tu] = t;
		}
	}
	return OK;
}
//表格形式打印
Status PrintSMatrix1(RLSMatrix M)
{
	int i;
	printf("i     j     Value\n");
	for(i = 1; i<= M.tu; i++)
		printf("%-6d%-6d%d\n",M.data[i].i, M.data[i].j, M.data[i].e);
	return OK;
}
//矩阵形式打印
Status PrintSMatrix2(RLSMatrix M)
{
	int i, j, p, q;
	for (i = 1; i<= M.mu; i++)
	{
		p = M.rpos[i];
		if(i< M.mu)q = M.rpos[i + 1];
		else q = M.tu + 1;

		for (j = 1; j<= M.nu; j++)
		{
			if(p< q && M.data[p].j == j)printf("%-6d",M.data[p++].e);
			else printf("%-6d",0);
		}
		printf("\n");
	}
	return OK;
}

Status CopySMatrix(RLSMatrix M, RLSMatrix *T)
{
	int i;
	T->mu = M.mu; T->nu = M.mu; T->tu = M.tu;
	for(i = 1; i<= M.tu; i++)
	{
		T->data[i].i = M.data[i].i;
		T->data[i].j = M.data[i].j;
		T->data[i].e = M.data[i].e;
	}
	for (i = 1; i<= M.tu; i++)T->rpos[i] = M.rpos[i];

	return OK;
}

Status AddSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix *Q)
{
	int m, n;
	Triple t;
	int num[MAXRC + 1];		//辅助数组,储存 Q 的每行的非零元个数
	if(M.mu != N.mu)return ERROR;
	if(M.nu != N.nu)return ERROR;

	Q->mu = M.mu; Q->nu = M.nu; Q->tu = 0;

	for(m = n = 1; m<= M.tu || n<= N.tu; )
	{			
		if(M.data[m].i == N.data[n].i && 
			M.data[m].j == N.data[n].j)//如果该点在 N,M 中位置一样
		{
			if((t.e = M.data[m].e + N.data[n].e) != 0)
			{
				t.i = M.data[m].i; 
				t.j = M.data[m].j;
				Q->data[++Q->tu] = t;
			}
			m++; n++;
		}
		else if(m<= M.tu && M.data[m].i< N.data[n].i || 
			(M.data[m].i == N.data[n].i && M.data[m].j< N.data[n].j))
		{				//如果该点在 M 中的位置后于 N
			Q->data[++Q->tu] = M.data[m];
			m++;
		}
		else	//如果该点在 M 中的位置前于 N
		{
			Q->data[++Q->tu] = N.data[n];
			n++;
		}
	}

	Q->rpos[1] = 1;
	for(m = 1; m<= Q->mu; m++) num[m] = 0;
	for(m = 1; m<= Q->tu; m++) num[Q->data[m].i] ++;
	for(m = 2; m<= Q->mu; m++) Q->rpos[m] = Q->rpos[m - 1] + num[m - 1];

	return OK;
}

Status MultSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix *Q)
{
	int i, mRow;			//计数器
	int nRow;			//记录N的行数,这一行要与M中当前处理元素分别相乘
	int mp, mq, np, nq;		//位置指示:mp = M.rpos[当前处理行];mq = M.rops[当前处理行 + 1]
					//nq, nq 理同。循环for(;p< q;p++)遍历当前处理行
	int qCol,ctemp[MAXRC + 1];	//累加器及其计数器
	Triple t;

	if(M.nu != N.mu)return ERROR;

	Q->mu = M.mu; Q->nu = N.nu; Q->tu = 0;
	if(M.tu * N.tu == 0)
	{
		for(i = 1; i<= Q->mu;i++)Q->rpos[i] = 1;
		return OK;
	}

	for (mRow = 1; mRow<= M.mu; mRow++)//处理每行
	{
		for(i = 1; i<= Q->nu; i++)ctemp[i] = 0;
		Q->rpos[mRow] = Q->tu + 1;

		if(mRow< M.mu) mq = M.rpos[mRow + 1];//如果不是最后一行
		else mq = M.tu + 1;

		for(mp = M.rpos[mRow]; mp< mq; mp++)//处理每个元素
		{
			nRow = M.data[mp].j;	//比如,元素(1,2,3)要与3相乘的是N中第2行所有元素
			if(nRow< N.mu) nq = N.rpos[nRow + 1];
			else nq = N.tu + 1;

			for(np = N.rpos[nRow]; np< nq; np++)//Q中的每个元素值,分N.mu次累加
			{
				qCol = N.data[np].j;	//Q的列等于N的列
				ctemp[qCol] += M.data[mp].e * N.data[np].e;
			}
		}

		for(qCol = 1; qCol<= Q->nu; qCol++)
		{
			t.i = mRow; t.j = qCol;
			t.e = ctemp[qCol];
			if(ctemp[qCol]) Q->data[++Q->tu] = t;
		}
	}
	return OK;
}
//Fast transpose
Status TransposeSMatrix(RLSMatrix M, RLSMatrix *T)
{
	int i;
	int col, p;
	int num[MAXRC + 1], cpot[MAXRC + 1];

	T->mu = M.nu; T->nu = M.mu; T->tu = M.tu;
	if(M.tu == 0)
	{
		for(i = 1; i<= T->mu; i++) T->rpos[i] = 1;
		return OK;
	}

	for(i = 1; i<= M.nu; i++) num[i] = 0;	//M每列元素个数置0
	for(i = 1; i<= M.tu; i++) num[M.data[i].j]++;	//求值
	
	T->rpos[1] = cpot[1] = 1;	//求copt
	for(i = 2; i<= M.nu; i++)
	{
		cpot[i] = cpot[i - 1] + num[i - 1];
		T->rpos[i] = cpot[i];	//每列的第一个即是转置后每行的第一个
	}

	for(i = 1; i<= M.tu; i++)
	{
		col = M.data[i].j; p = cpot[col];
		T->data[p].i = M.data[i].j; T->data[p].j = M.data[i].i;
		T->data[p].e = M.data[i].e;
		cpot[col]++;
	}
	return OK;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值