稀疏矩阵的三元组表示(ANSI C)

1、基本结构定义

typedef int elem_type;

typedef struct triplet
{
	int r, c;
	elem_type elem;
}triplet;

typedef struct sparse_mat
{
	triplet * data;
	int rows;
	int cols;
	int n_elem;
}sparse_mat;
2、从数据文件初始化、释放
void init_sparse_mat( sparse_mat * mat, const char * file )
{
	FILE * fp = fopen( file, "r+" );
	int rows, cols, n_elem = 0;
	int i, j, k = 0;
	elem_type e;
	assert( fp != NULL );
	fscanf( fp, "%d %d", &rows, &cols );
	mat->rows = rows;
	mat->cols = cols;
	for( i = 0; i < rows; ++i )
	{
		for( j = 0; j < cols; ++j )
		{
			fscanf( fp, "%d", &e );
			if( e != 0 )
				++n_elem;
		}
	}
	mat->n_elem = n_elem;

	//rewind( fp );
	fseek( fp, 2 * sizeof( int ), SEEK_SET );

	mat->data = ( triplet * )malloc( sizeof( triplet ) * n_elem );
	for( i = 0; i < rows; ++i )
	{
		for( j = 0; j < cols; ++j )
		{
			fscanf( fp, "%d", &e );
			if( e != 0 )
			{
				mat->data[k].r = i;
				mat->data[k].c = j;
				mat->data[k].elem = e;
				++k;
			}
		}
	}
	fclose( fp );
}

void free_sparse_mat( sparse_mat * mat )
{
	if( mat->data != NULL )
		free( mat->data );
	mat->rows = mat->cols = mat->n_elem = 0;
}
3、矩阵转置
void transpose_sparse_mat( sparse_mat * src, sparse_mat * dst )
{
	int i, j, k = 0;
	dst->rows = src->cols;
	dst->cols = src->rows;
	dst->n_elem = src->n_elem;
	dst->data = ( triplet * )malloc( sizeof( triplet ) * dst->n_elem );

	if( dst->n_elem > 0 )
	{
		for( i = 0; i < src->cols; ++i )
		{
			for( j = 0; j < src->n_elem; ++j )
			{
				if( i == src->data[j].c )
				{
					dst->data[k].r = src->data[j].c;
					dst->data[k].c = src->data[j].r;
					dst->data[k].elem = src->data[j].elem;
					++k;
				}
			}
		}
	}
}
4、快速转置

void fast_transpose( sparse_mat * src, sparse_mat * dst )
{
	int * ins_pos = NULL, * n_elem = NULL;
	int rows = src->rows, cols = src->cols;
	int i, j;
	dst->rows = cols;
	dst->cols = rows;
	dst->n_elem = src->n_elem;
	if( dst->data != NULL )
		free( dst->data );
	dst->data = ( triplet * )malloc( sizeof( triplet ) * dst->n_elem );
	
	ins_pos = ( int * )malloc( sizeof( int ) * rows );
	n_elem = ( int * )malloc( sizeof( int ) * cols );
	memset( ins_pos, 0, sizeof( int ) * cols );
	memset( n_elem, 0, sizeof( int ) * cols );

	/* first round of scanning */
	for( i = 0; i < src->n_elem; ++i )
	{
		++n_elem[src->data[i].c];
	}

	ins_pos[0] = 0;
	for( i = 1; i < src->cols; ++i )
	{
		ins_pos[i] = ins_pos[i - 1] + n_elem[i - 1];
	}

	/* second round of scanning */
	for( i = 0; i < src->n_elem; ++i )
	{
		j = ins_pos[src->data[i].c]++;
		dst->data[j].elem = src->data[i].elem;
		dst->data[j].r = src->data[i].c;
		dst->data[j].c = src->data[i].r;
	}
}
5、矩阵的输出

void disp_sparse_mat( sparse_mat * mat )
{
	elem_type ** data = NULL;
	int rows, cols, i, j;
	int r, c;
	rows = mat->rows;
	cols = mat->cols;

	data = ( elem_type ** )malloc( sizeof( elem_type * ) * rows );
	for( i = 0; i < rows; ++i )
	{
		data[i] = ( elem_type * )malloc( sizeof( elem_type ) * cols );
		memset( data[i], 0, cols * sizeof( elem_type ) );
	}

	for( i = 0; i < mat->n_elem; ++i )
	{
		r = mat->data[i].r;
		c = mat->data[i].c;
		data[r][c] = mat->data[i].elem;
	}

	for( i = 0; i < rows; ++i )
	{
		for( j = 0; j < cols; ++j )
		{
			printf( "%d ", data[i][j] );
		}
		printf( "\n" );
	}
}

6、完整程序

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

typedef int elem_type;

typedef struct triplet
{
	int r, c;
	elem_type elem;
}triplet;

typedef struct sparse_mat
{
	triplet * data;
	int rows;
	int cols;
	int n_elem;
}sparse_mat;


void init_sparse_mat( sparse_mat * mat, const char * file )
{
	FILE * fp = fopen( file, "r+" );
	int rows, cols, n_elem = 0;
	int i, j, k = 0;
	elem_type e;
	assert( fp != NULL );
	fscanf( fp, "%d %d", &rows, &cols );
	mat->rows = rows;
	mat->cols = cols;
	for( i = 0; i < rows; ++i )
	{
		for( j = 0; j < cols; ++j )
		{
			fscanf( fp, "%d", &e );
			if( e != 0 )
				++n_elem;
		}
	}
	mat->n_elem = n_elem;

	//rewind( fp );
	fseek( fp, 2 * sizeof( int ), SEEK_SET );

	mat->data = ( triplet * )malloc( sizeof( triplet ) * n_elem );
	for( i = 0; i < rows; ++i )
	{
		for( j = 0; j < cols; ++j )
		{
			fscanf( fp, "%d", &e );
			if( e != 0 )
			{
				mat->data[k].r = i;
				mat->data[k].c = j;
				mat->data[k].elem = e;
				++k;
			}
		}
	}
	fclose( fp );
}

void free_sparse_mat( sparse_mat * mat )
{
	if( mat->data != NULL )
		free( mat->data );
	mat->rows = mat->cols = mat->n_elem = 0;
}

void disp_sparse_mat( sparse_mat * mat )
{
	elem_type ** data = NULL;
	int rows, cols, i, j;
	int r, c;
	rows = mat->rows;
	cols = mat->cols;

	data = ( elem_type ** )malloc( sizeof( elem_type * ) * rows );
	for( i = 0; i < rows; ++i )
	{
		data[i] = ( elem_type * )malloc( sizeof( elem_type ) * cols );
		memset( data[i], 0, cols * sizeof( elem_type ) );
	}

	for( i = 0; i < mat->n_elem; ++i )
	{
		r = mat->data[i].r;
		c = mat->data[i].c;
		data[r][c] = mat->data[i].elem;
	}

	for( i = 0; i < rows; ++i )
	{
		for( j = 0; j < cols; ++j )
		{
			printf( "%d ", data[i][j] );
		}
		printf( "\n" );
	}
}

void transpose_sparse_mat( sparse_mat * src, sparse_mat * dst )
{
	int i, j, k = 0;
	dst->rows = src->cols;
	dst->cols = src->rows;
	dst->n_elem = src->n_elem;
	dst->data = ( triplet * )malloc( sizeof( triplet ) * dst->n_elem );

	if( dst->n_elem > 0 )
	{
		for( i = 0; i < src->cols; ++i )
		{
			for( j = 0; j < src->n_elem; ++j )
			{
				if( i == src->data[j].c )
				{
					dst->data[k].r = src->data[j].c;
					dst->data[k].c = src->data[j].r;
					dst->data[k].elem = src->data[j].elem;
					++k;
				}
			}
		}
	}
}

void fast_transpose( sparse_mat * src, sparse_mat * dst )
{
	int * ins_pos = NULL, * n_elem = NULL;
	int rows = src->rows, cols = src->cols;
	int i, j;
	dst->rows = cols;
	dst->cols = rows;
	dst->n_elem = src->n_elem;
	if( dst->data != NULL )
		free( dst->data );
	dst->data = ( triplet * )malloc( sizeof( triplet ) * dst->n_elem );
	
	ins_pos = ( int * )malloc( sizeof( int ) * rows );
	n_elem = ( int * )malloc( sizeof( int ) * cols );
	memset( ins_pos, 0, sizeof( int ) * cols );
	memset( n_elem, 0, sizeof( int ) * cols );

	/* first round of scanning */
	for( i = 0; i < src->n_elem; ++i )
	{
		++n_elem[src->data[i].c];
	}

	ins_pos[0] = 0;
	for( i = 1; i < src->cols; ++i )
	{
		ins_pos[i] = ins_pos[i - 1] + n_elem[i - 1];
	}

	/* second round of scanning */
	for( i = 0; i < src->n_elem; ++i )
	{
		j = ins_pos[src->data[i].c]++;
		dst->data[j].elem = src->data[i].elem;
		dst->data[j].r = src->data[i].c;
		dst->data[j].c = src->data[i].r;
	}
}

int main( int argc, char * argv[] )
{
	char file[] = "data.txt";
	sparse_mat src, dst, dst2;

	dst.data = dst2.data = NULL;

	init_sparse_mat( &src, file );
	disp_sparse_mat( &src );

	printf( "------ general transpose -------\n" );
	transpose_sparse_mat( &src, &dst );
	disp_sparse_mat( &dst );

	printf( "------- fast transpose ---------\n" );
	fast_transpose( &src, &dst2 );
	disp_sparse_mat( &dst2 );

	free_sparse_mat( &src );
	free_sparse_mat( &dst );
	free_sparse_mat( &dst2 );
}
7、数据文件格式
5 6
0 0 0 0 0 0
1 0 0 0 2 0
0 0 0 3 0 0
4 0 5 0 0 6
0 0 0 0 7 0

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值