使用顺序存储结构存储稀疏矩阵,并实现转置和乘法运算。
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
//顺序结构的稀疏矩阵:转置+乘法
#define xishu_max 100
#define xishu_increment 100
typedef struct{
int i,j;
int value;
}array_element;
typedef struct{
int array_row, array_column;
int array_valid;
int *row_first_index; //每行第一个非零元所在顺序存储结构中
array_element *array_head;
char name[20];
}myarray;
typedef enum{
ERROR = 0,
SUCCESS = ~ERROR
}error_status;
void paixu_array(myarray *arr){
int k, kk;
int i_temp, j_temp, value_temp;
for(kk=0; kk<arr->array_valid; kk++){
for(k=1; k<arr->array_valid-kk; k++){
if((arr->array_head+k-1)->i>(arr->array_head+k)->i){
i_temp = (arr->array_head+k-1)->i;
j_temp = (arr->array_head+k-1)->j;
value_temp = (arr->array_head+k-1)->value;
(arr->array_head+k-1)->i = (arr->array_head+k)->i;
(arr->array_head+k-1)->j = (arr->array_head+k)->j;
(arr->array_head+k-1)->value = (arr->array_head+k)->value;
(arr->array_head+k)->i = i_temp;
(arr->array_head+k)->j = j_temp;
(arr->array_head+k)->value = value_temp;
}
else if((arr->array_head+k-1)->i==(arr->array_head+k)->i){
if((arr->array_head+k-1)->j>(arr->array_head+k)->j){
j_temp = (arr->array_head+k-1)->j;
value_temp = (arr->array_head+k-1)->value;
(arr->array_head+k-1)->j = (arr->array_head+k)->j;
(arr->array_head+k-1)->value = (arr->array_head+k)->value;
(arr->array_head+k)->j = j_temp;
(arr->array_head+k)->value = value_temp;
}
}
}
}
}
void generate_row_first_index(myarray *arr){
int i_temp, k, kk;
i_temp = 1, k = 0;
for(kk=0; kk<arr->array_row; kk++){
*(arr->row_first_index+kk) = -1;
}
while(k<arr->array_valid){
if((arr->array_head+k)->i > i_temp){
i_temp++;
continue;
}
else if((arr->array_head+k)->i == i_temp){
*(arr->row_first_index+i_temp-1) = k;
k++, i_temp++;
if(i_temp>arr->array_row)
break;
}
else
k++;
}
}
error_status input_array(myarray *arr){
int k,kk;
arr->row_first_index = NULL;
printf("key in your array's info:\n");
printf("array_row:"); scanf("%d", &arr->array_row);
printf("array_column:"); scanf("%d", &arr->array_column);
printf("array_valid:"); scanf("%d", &arr->array_valid);
printf("array_name:"); scanf("%s", arr->name);
if(arr->array_column>0&&arr->array_row>0&&arr->array_valid<=arr->array_column*arr->array_row){
if((arr->array_head = (array_element*)malloc(arr->array_valid*sizeof(array_element)))!=NULL){
for(k=0; k<arr->array_valid; k++){
printf("array_element:i j value ");
scanf("%d %d %d", &(arr->array_head+k)->i, &(arr->array_head+k)->j, &(arr->array_head+k)->value);
if((arr->array_head+k)->i<1||(arr->array_head+k)->j<1){
free(arr->array_head);
return ERROR;
}
}
//对输入完成的稀疏矩阵元素进行排序,以行为序排序
paixu_array(arr);
}
else{
return ERROR;
}
}
if((arr->row_first_index = (int*)malloc(arr->array_row*sizeof(int)))!=NULL){
generate_row_first_index(arr);
}
else{
free(arr->array_head);
return ERROR;
}
}
void zhuanzhi_array(myarray *arr){
int k, temp;
temp = arr->array_column;
arr->array_column = arr->array_row;
arr->array_row = temp;
for(k=0; k<arr->array_valid; k++){
temp = (arr->array_head+k)->i;
(arr->array_head+k)->i = (arr->array_head+k)->j;
(arr->array_head+k)->j = temp;
}
paixu_array(arr);
generate_row_first_index(arr);
}
error_status multiple_array(myarray *A, myarray *B, myarray *AB){
array_element *AB_row_array;
int k, kk, num;
if(A->array_column!=B->array_row)
return ERROR;
AB->array_row = A->array_row;
AB->array_column = B->array_column;
AB->array_valid = 0;
if((AB->array_head = (array_element*)malloc(A->array_row*B->array_column*sizeof(array_element)))==NULL)
return ERROR;
if((AB->row_first_index = (int*)malloc(AB->array_row*sizeof(int)))==NULL){
free(AB->array_head);
return ERROR;
}
if((AB_row_array = (array_element*)malloc(B->array_column*sizeof(array_element)))==NULL){
free(AB->array_head);
free(AB->row_first_index);
return ERROR;
}
printf("key in mul_array's name:");
scanf("%s", AB->name);
for(k=0; k<B->array_column; k++){
(AB_row_array+k)->i = 0;
(AB_row_array+k)->j = 0;
(AB_row_array+k)->value = 0;
}
//无法预测A*B后AB非零元数量,AB先分配足够大的内存,如[0 0 1;0 0 1;0 0 1]*[0 0 0;0 0 0;1 1 1]=[1 1 1;1 1 1;1 1 1],如果AB非零元较多时,还必须将存储形式转变为一般矩阵顺序存储方式,以节省存储空间
for(k=0, num=1; k<A->array_valid; k++){
//if((num<A->array_row&&(k>=*(A->row_first_index+num)))||(num==A->array_row&&k==A->array_valid-1)){
if(num<A->array_row&&(k>=*(A->row_first_index+num))){
num++;
//将一行非零结果存入AB
for(kk=0; kk<B->array_column; kk++){
if((AB_row_array+kk)->value!=0){
(AB->array_head+AB->array_valid)->i = (AB_row_array+kk)->i;
(AB->array_head+AB->array_valid)->j = (AB_row_array+kk)->j;
(AB->array_head+AB->array_valid)->value = (AB_row_array+kk)->value;
AB->array_valid++;
}
}
for(kk=0; kk<B->array_column; kk++){
(AB_row_array+kk)->i = 0;
(AB_row_array+kk)->j = 0;
(AB_row_array+kk)->value = 0;
}
}
//计算一行数值
for(kk=0; kk<B->array_valid; kk++){
if((A->array_head+k)->j==(B->array_head+kk)->i){
(AB_row_array+(B->array_head+kk)->j-1)->value += (A->array_head+k)->value*(B->array_head+kk)->value;
(AB_row_array+(B->array_head+kk)->j-1)->i = (A->array_head+k)->i;
(AB_row_array+(B->array_head+kk)->j-1)->j = (B->array_head+kk)->j;
}
}
}
for(kk=0; kk<B->array_column; kk++){
if((AB_row_array+kk)->value!=0){
(AB->array_head+AB->array_valid)->i = (AB_row_array+kk)->i;
(AB->array_head+AB->array_valid)->j = (AB_row_array+kk)->j;
(AB->array_head+AB->array_valid)->value = (AB_row_array+kk)->value;
AB->array_valid++;
}
}
paixu_array(AB);
}
void output_array(myarray *arr){
int row,column,k;
//row = arr->array_row; column = arr->array_column;
printf("%s=\n", arr->name);
for(row=0, k=0; row<arr->array_row; row++){
for(column=0; column<arr->array_column; column++){
if(k<arr->array_valid){
if((arr->array_head+k)->i-1==row&&(arr->array_head+k)->j-1==column){
printf("%d ", (arr->array_head+k)->value);
k++;
}
else{
printf("0 ");
}
}
else{
printf("0 ");
}
}
printf("\n");
}
}
int main(void){
myarray A,B;
myarray AB;
input_array(&A);
input_array(&B);
output_array(&A);
output_array(&B);
multiple_array(&A, &B, &AB);
output_array(&AB);
system("pause");
return 0;
}