稀疏矩阵存储、转置、乘法运算

使用顺序存储结构存储稀疏矩阵,并实现转置和乘法运算。

#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;
}


posted @ 2014-05-29 15:10  浴火重生-xhyz  阅读(366)  评论(0编辑  收藏  举报