数据结构——稀疏矩阵的转置算法

本篇文章的代码基于【数据结构】【严蔚敏】【清华大学】

不是很想分函数来一遍解释
信息基本上都在注解里
直接上完整代码好了

#include <stdio.h> 
#include <stdlib.h>
#define MAXSIZE 100 // 非零元个数的最大值
typedef int ElemType; 
typedef int Status; 
#define OK 1
#define N 4

struct Triple {
	int i,j; 				// 行下标,列下标
	ElemType e; 			// 非零元素值
};

struct TSMatrix {
	Triple data[MAXSIZE+1]; // 非零元三元组表,data[0]未用
	int mu,nu,tu; 			// 矩阵的行数、列数和非零元个数
};
 
// 带行连接信息的三元组表 
typedef struct{
	Triple data[MAXSIZE+1]; // 非零元三元组表,data[0]未用
	int rpos[MAXSIZE+1];	//	各行的第一个非零元的位置表 
	int mu,nu,tu; 			// 矩阵的行数、列数和非零元个数
}RLSMatrix;

Status TransposeSMatrix(TSMatrix M,TSMatrix &T)
{
	// 求稀疏矩阵M的转置矩阵T。算法5.1
	// 时间复杂度为O(nu*tu) 
	// 当tu和mu*nu同一个数量级时,时间复杂度会变为O(mu*nu^2)
	//  因此适用于tu<<mu*nu情况时 
	int p,q,col;
	T.mu=M.nu;
	T.nu=M.mu;
	T.tu=M.tu;
	if(T.tu) {
		q=1;
		for(col=1; col<=M.nu; ++col)
			for(p=1; p<=M.tu; ++p)
				if(M.data[p].j==col) {
					T.data[q].i=M.data[p].j;
					T.data[q].j=M.data[p].i;
					T.data[q].e=M.data[p].e;
					++q;
				}
	}
	return OK;
}

Status TransposeSMatrix(RLSMatrix M,RLSMatrix &T)
{
	// 求稀疏矩阵M的转置矩阵T. 算法5.2 快速转置 
	int p,q,t,col,*num;
	num=(int *)malloc((M.nu+1)*sizeof(int));
	T.mu=M.nu;
	T.nu=M.mu;
	T.tu=M.tu;
	if(T.tu) {
		for(col=1; col<=M.nu; ++col)
			num[col]=0;  				// 设初值
		for(t=1; t<=M.tu; ++t) 			// 求M中每一列非零元个数
			++num[M.data[t].j];
		T.rpos[1]=1;
		for(col=2; col<=M.nu; ++col) 	// 求M中第col中第一个非零元在T.data中的序号
			T.rpos[col]=T.rpos[col-1]+num[col-1];
		for(col=1; col<=M.nu; ++col)    // T.rpos[col]的值不方便改变(别的操作会用到),故把值给到临时变量num[col] 
			num[col]=T.rpos[col];
		for(p=1; p<=M.tu; ++p) {
			col=M.data[p].j;
			q=num[col];
			T.data[q].i=M.data[p].j;
			T.data[q].j=M.data[p].i;
			T.data[q].e=M.data[p].e;
			++num[col];
		}
	}
	free(num);
	return OK;
}

void initmatrix(TSMatrix &a,ElemType a1[][N])
{
	a.mu=N;
	a.nu=N;
	a.tu=0;
	for(int i=1;i<=a.mu;i++)
		for(int j=1;j<=a.nu;j++)
		{
			if(a1[i-1][j-1]!=0)
			{
				a.tu++;
				a.data[a.tu].i=i;
				a.data[a.tu].j=j;
				a.data[a.tu].e=a1[i-1][j-1];
			} 
		}
}

void printmatrix(TSMatrix a)
{
	a.tu=1;
	for(int i=1;i<=a.mu;i++)
	{
		for(int j=1;j<=a.nu;j++)
		{
			
			if(a.data[a.tu].i==i&&a.data[a.tu].j==j)	
			{
				printf("%d ",a.data[a.tu++].e);
			}
			else
			printf("0 ");
		}
		printf("\n");
	}
		
}
int main()
{
	ElemType  a1[N][N]= {{1,0,3,0},{0,1,0,0},{0,0,1,0},{0,0,1,1}};
	
	TSMatrix M1,T1;		//这里用的是第一个三元组表和第一个转置函数,暂时没用带行连接信息的三元组表 
	initmatrix(M1,a1);  //初始化,把二维数组转换成非零三元组表 
	//printmatrix(M1);	//看一看转置前的样子
	 
	TransposeSMatrix(M1,T1); 
	printmatrix(T1);	//输出转置后的矩阵 
}
posted @ 2018-12-02 15:29  聚落  阅读(3274)  评论(0编辑  收藏  举报