//稀疏矩阵的转置
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define ELEM_TYEP int
#define MAX_SIZE 100
typedef struct
{
int row; //矩阵中某一元素的行数
int col; //列数
ELEM_TYEP elem; //元素值
}elem;
typedef struct
{
elem data[MAX_SIZE];
int row_num; //稀疏矩阵的总行数
int col_num; //总列数
int elem_num; //非零元素个数
}sparse_matrix;
void create_sparse_matrix(sparse_matrix *matrix)
{
matrix->row_num = 6;
matrix->col_num = 5;
matrix->elem_num = 8;
/*****行三元组(测试数据)*****/
matrix->data[0].row = 0;
matrix->data[0].col = 1;
matrix->data[0].elem = 12;
matrix->data[1].row = 0;
matrix->data[1].col = 2;
matrix->data[1].elem = 9;
matrix->data[2].row = 2;
matrix->data[2].col = 0;
matrix->data[2].elem = -3;
matrix->data[3].row = 2;
matrix->data[3].col = 4;
matrix->data[3].elem = 14;
matrix->data[4].row = 3;
matrix->data[4].col = 2;
matrix->data[4].elem = 24;
matrix->data[5].row = 4;
matrix->data[5].col = 1;
matrix->data[5].elem = 18;
matrix->data[6].row = 5;
matrix->data[6].col = 0;
matrix->data[6].elem = 15;
matrix->data[7].row = 5;
matrix->data[7].col = 3;
matrix->data[7].elem = -7;
/*****测试数据*****/
return ;
}
void print_sparse_matrix(sparse_matrix matrix)
{
int i = 0;
for(i = 0; i < matrix.elem_num; i++)
{
printf("|%-3d,%-3d%,%3d|\n", matrix.data[i].row, matrix.data[i].col, matrix.data[i].elem);
}
printf("\n");
return ;
}
void print_full_matrix(sparse_matrix matrix)
{
int i = 0;
int j = 0;
int k = 0;
for(i = 0; i < matrix.row_num; i++)
{
for(j = 0; j < matrix.col_num; j++)
{
if(i == matrix.data[k].row)
{
if(j == matrix.data[k].col)
{
printf("%-3d", matrix.data[k].elem);
k++;
continue;
}
}
printf("0 ");
}
printf("\n");
}
printf("\n");
return ;
}
//一般转置方法
void common_matrix_transpose(sparse_matrix ma, sparse_matrix *mb)
{
int k = 0;
int i = 0, j = 0;
mb->col_num = ma.row_num;
mb->row_num = ma.col_num;
mb->elem_num = ma.elem_num;
if(ma.elem_num)
{
for(i = 0; i < ma.col_num; i++)
{
for(j = 0; j < ma.elem_num; j++)
{
if(ma.data[j].col == i)
{
mb->data[k].col = ma.data[j].row;
mb->data[k].row = ma.data[j].col;
mb->data[k].elem = ma.data[j].elem;
k++;
}
}
}
}
return ;
}
//快速转置
void quick_matrix_transpose(sparse_matrix ma, sparse_matrix *mb)
{
int i = 0, j = 0;
int k = 0;
int *cpot; //cpot[i]表示ma中第i列的第一个非0元素,在三元组mb.data[]中的位置
int *num; //num[i]表示ma中第i列的非零元素的个数
cpot = (int *)malloc(ma.col_num * sizeof(int));
num = (int *)malloc(ma.col_num * sizeof(int));
mb->col_num = ma.row_num;
mb->row_num = ma.col_num;
mb->elem_num = ma.elem_num;
if(mb->elem_num)
{
//初始化num
for(i = 0; i < ma.col_num; i++)
{
num[i] = 0;
}
//获取每一列的非零元素个数,注意这种赋值方法
for(i = 0; i < ma.elem_num; i++)
{
num[ma.data[i].col]++;
}
//填充cpot数组
cpot[0] = 0;
for(i = 1; i < ma.col_num; i++)
{
cpot[i] = cpot[i-1] + num[i-1];
}
//ma.data[i]项元素在mb.data[]中的位置为j
for(i = 0; i < ma.elem_num; i++)
{
j = ma.data[i].col;
k = cpot[j];
mb->data[k].col = ma.data[i].row;
mb->data[k].row = ma.data[i].col;
mb->data[k].elem = ma.data[i].elem;
cpot[j]++;
}
}
free(num);
free(cpot);
return ;
}
int main(int argc, char *argv[])
{
sparse_matrix ma;
sparse_matrix mb;
create_sparse_matrix(&ma);
print_sparse_matrix(ma);
print_full_matrix(ma);
// common_matrix_transpose(ma, &mb);
quick_matrix_transpose(ma, &mb);
print_sparse_matrix(mb);
print_full_matrix(mb);
return 0;
}