数据结构:稀疏矩阵的三元组顺序表


//----------------稀疏矩阵的三元组顺序存储表示-------------------
//按行序优先存储

#include <iostream>
#include <cassert>
using namespace std;
#define MAXSIZE 2000 //假设非零元个数的最大值为2000,动态分配更好一些,这里只是做个测验
typedef int ElemType;
typedef struct  
{
	int i;  //行下标
	int j;  //列下标
	ElemType val; //值
}Triple;

typedef struct  
{
	Triple data[MAXSIZE];  //非零元三元组表,动态分配更好一些,这里只是做个测验
	int rows;  //行数
	int cols; //列数
	int nzs;   //非零(no-zero)元个数
}TSMatrix;

//创建稀疏矩阵
void CreateTSMatrix( TSMatrix& M )
{
	M.nzs = 0;
	M.rows = 0;
	M.cols = 0;
	cout << "输入矩阵的行数和列数:";
	cin >> M.rows >> M.cols;
	assert( M.rows > 0 && M.cols > 0 );
	cout << "请按顺序输入一个" << M.rows << "行"
		<< M.cols << "列的矩阵:" << endl;
	for( int i = 0; i < M.rows; ++i )
	{
		for ( int j = 0; j < M.cols; ++j )
		{
			int val;
			cin >> val;
			if ( val != 0 )
			{
				M.data[M.nzs].i = i;
				M.data[M.nzs].j = j;
				M.data[M.nzs].val = val;
				M.nzs++;
			}
		}
	}
}

//打印该稀疏矩阵
/*
*	按照T.data中三元组的次序依次在M.data中找到相应的三元组进行转置。换句话说,就是
*   按矩阵M的列序进行转置。
*/
void PrintTSMatrix( const TSMatrix& M )
{
	int k = 0; 
	for ( int i = 0; i < M.rows; ++i )
	{
		for ( int j = 0; j < M.cols; ++j )
		{
			if ( k < M.nzs &&  M.data[k].i == i && M.data[k].j == j )
			{
				cout << M.data[k].val << " ";
				++k;
			}
			else
			{
				cout << 0 << " ";
			}
		}
		cout << endl;
	}
}

//求M的转置矩阵T
/*
*	按照T.data中三元组的次序依次在M.data中找到相应的三元组进行转置。
*	换句话说,按照矩阵M的列序来进行转置。
*/
void TransposeTSMatrix( const TSMatrix& M, TSMatrix& T )
{
	T.cols = M.rows;
	T.rows = M.cols;
	T.nzs = M.nzs;
	if ( M.nzs )
	{
		int cnt = 0;
		for ( int col = 0; col < M.cols; ++col )
		{
			for ( int p = 0; p < M.nzs; ++p )
			{
				if ( col == M.data[p].j  )
				{
					T.data[cnt].i = M.data[p].j;
					T.data[cnt].j = M.data[p].i;
					T.data[cnt].val = M.data[p].val;
					++cnt;
				}
			}
		}
	}
}

/*
*	按照M.data中三元组的次序进行转置,并将转置后的三元组置入
*	T中恰当的位置。如果能预先确定矩阵M中每一列地第一个非零元
*	在T.data中应有的位置,那么在对M.data中的三元组依次转置时,
*	便可直接放到T.data中恰当的位置上去。
*/
void TransposeTSMatrixEx( const TSMatrix& M, TSMatrix& T )
{
	T.cols = M.rows;
	T.rows = M.cols;
	T.nzs = M.nzs;
	if ( M.nzs )
	{
		int *pNum = new int[M.cols];//表示矩阵M中第col列中非零元素的个数
		for ( int i = 0; i < M.cols; ++i )
		{
			*(pNum+i) = 0;
		}
		for ( int i = 0; i < M.nzs; ++i )
		{
			++( *(pNum +  M.data[i].j ) );
		}

		int*  pCpot = new int [M.cols ]; //指示M中第col列的第一个非零元素在T.data中的恰当位置
		*(pCpot) = 0;
		for ( int i = 1; i < M.cols; ++i )
		{
			*(pCpot + i) = *(pCpot+i-1) + *(pNum+i-1);
		}

		for ( int i = 0; i < M.nzs; ++i )
		{
			int col = M.data[i].j;
			int q = *(pCpot + col);
			T.data[q].i = M.data[i].j;
			T.data[q].j = M.data[i].i;
			T.data[q].val = M.data[i].val;
			++( *(pCpot + col));
		}
		delete[] pNum;
		delete[] pCpot;
	}
}

//判断M[i][j]是否是非零,若非0,则用iIndex返回该元素在三元组表中
//的位置,否则iIndex为-1
bool IsNoZeroAtPos( const TSMatrix& M, int i, int j, int& iIndex )
{	
	for( int k = 0; k < M.nzs; ++k )
	{
		if ( M.data[k].i == i && M.data[k].j == j )
		{
			iIndex = k;
			return true;//非0
		}
	}
	iIndex = -1;
	return false; //为0

}

//矩阵的相加,相减的操作与相加类似
//时间复杂度为O(rows*cols*nzs),算法非常不好
void AddTSMatrix( const TSMatrix& M, const TSMatrix& N, TSMatrix& Q )
{
	assert( M.rows == N.rows && M.cols == N.cols );
	if ( M.rows != N.rows || M.cols != N.cols )
	{
		Q.rows = 0;
		Q.cols = 0;
		return;
	}
	int p = 0;
	Q.cols = M.cols;
	Q.rows = M.rows;
	Q.nzs = 0;
	for ( int i = 0; i < Q.rows; ++i )
	{
		for ( int j = 0; j < Q.cols; ++j )
		{
			int iIndexM;
			int iIndexN;
			bool bIsNoZeroM = IsNoZeroAtPos( M, i, j, iIndexM );
			bool bIsNoZeroN = IsNoZeroAtPos( N, i, j, iIndexN );

			if ( bIsNoZeroM && bIsNoZeroN )//M[i][j]与N[i][j]均非0,相加
			{
				Q.data[p].i = i;
				Q.data[p].j = j;
				Q.data[p].val = M.data[iIndexM].val + N.data[iIndexN].val;
				++p;
				++(Q.nzs);
			}
			else if ( bIsNoZeroM && !bIsNoZeroN )
			{
				Q.data[p].i = i;
				Q.data[p].j = j;
				Q.data[p].val = M.data[iIndexM].val;
				++p;
				++(Q.nzs);
			}
			else if ( !bIsNoZeroM && bIsNoZeroN)
			{
				Q.data[p].i = i;
				Q.data[p].j = j;
				Q.data[p].val = N.data[iIndexN].val;
				++p;
				++(Q.nzs);

			}
			else
			{
				;
			}
		}
	}

}


//稀疏矩阵的相乘,时间复杂度很高!!设计的不够好
void MultTSMatrix( const TSMatrix& M, const TSMatrix& N, TSMatrix& Q )
{
	assert( M.cols == N.rows );
	if ( M.cols != N.rows )
	{
		Q.rows = 0;
		Q.cols = 0;
		return;
	}
	int p = 0;
	Q.rows = M.rows;
	Q.cols = N.cols;
	Q.nzs = 0;
	//采用矩阵相乘的经典算法
	for ( int i = 0; i < Q.rows; ++i )
	{
		for ( int j = 0; j < Q.cols; ++j )
		{
			int tol = 0;
			for ( int k = 0; k < M.cols; ++k )
			{
				int iIndexM;
				int iIndexN;
				bool bIsNoZeroM = IsNoZeroAtPos( M, i, k, iIndexM );
				bool bIsNoZeroN = IsNoZeroAtPos( N, k, j, iIndexN );
				if ( bIsNoZeroM && bIsNoZeroN )//当两个都不为0时,才进行相乘
				{
					tol += M.data[iIndexM].val * N.data[iIndexN].val;
				}
			}
			if ( 0 != tol )//若为0,则表明乘积结果为0
			{
				Q.data[p].i = i;
				Q.data[p].j = j;
				Q.data[p].val = tol;
				++p;
				++(Q.nzs);
			}

		}
	}



}




int main( int argc, char** argv )
{
	TSMatrix M;
	CreateTSMatrix( M );
	system("cls");
	cout << "当前矩阵M:" << endl;
	PrintTSMatrix( M );
	cout << endl;
	TSMatrix T;
	TransposeTSMatrix( M, T );
	cout << "第一种方法转置后的矩阵T:" << endl;
	PrintTSMatrix( T );
	cout << endl;
	TransposeTSMatrixEx( M, T );
	cout << "第二种方法转置后的矩阵T:" << endl;
	PrintTSMatrix( T );
	cout << endl;

	TSMatrix Q;
	AddTSMatrix( M, T, Q );
	cout << "矩阵M和T相加的结果为:"<< endl;
	PrintTSMatrix( Q );
	cout << endl;

	MultTSMatrix( M, T, Q );
	cout << "矩阵M和T相乘的结果为:"<< endl;
	PrintTSMatrix( Q );
	cout << endl;

	return 0;
}


  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是Python代码示例,演示如何将稀疏矩阵转换为三元组表,以及如何将三元组表输出为稀疏矩阵。 ```python # 稀疏矩阵转为三元组表 def sparse_to_triplet(sparse_matrix): triplet = [] rows, cols = sparse_matrix.shape for i in range(rows): for j in range(cols): if sparse_matrix[i, j] != 0: triplet.append((i, j, sparse_matrix[i, j])) return triplet, rows, cols # 三元组表转为稀疏矩阵 def triplet_to_sparse(triplet, rows, cols): sparse_matrix = np.zeros((rows, cols)) for i, j, value in triplet: sparse_matrix[i, j] = value return sparse_matrix # 测试代码 import numpy as np # 创建一个稀疏矩阵 sparse_matrix = np.array([[1, 0, 0, 0], [0, 2, 0, 0], [0, 0, 0, 3]]) # 将稀疏矩阵转为三元组表 triplet, rows, cols = sparse_to_triplet(sparse_matrix) print("稀疏矩阵转为三元组表:") print("triplet:", triplet) print("rows, cols:", rows, cols) # 将三元组表转为稀疏矩阵 sparse_matrix = triplet_to_sparse(triplet, rows, cols) print("三元组表转为稀疏矩阵:") print(sparse_matrix) ``` 输出结果如下: ``` 稀疏矩阵转为三元组表: triplet: [(0, 0, 1), (1, 1, 2), (2, 3, 3)] rows, cols: 3 4 三元组表转为稀疏矩阵: [[1. 0. 0. 0.] [0. 2. 0. 0.] [0. 0. 0. 3.]] ``` 在上面的代码中,我们首先创建了一个稀疏矩阵,然后调用 `sparse_to_triplet` 方法将其转为三元组表,再调用 `triplet_to_sparse` 方法将三元组表转为稀疏矩阵,并将转换结果输出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值