您的位置:首页 > 其它

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

2012-06-03 02:57 239 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c dst fp null file struct
相关文章推荐