使用顺序存储结构存储稀疏矩阵,并实现转置和乘法运算。
#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: "); 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= ", 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(" "); } } 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; }