数据结构学习五(稀疏矩阵的实现,三元组)

使用三元组实现稀疏矩阵的建立、逆转、乘法。

乘法没有使用附加向量,是自己想得。有错误请谅解。性能可能没有书上介绍的好。


代码如下:(本代码只经过本人的简单测试,可能存在问题。请相信自己的能力,敢于质疑。欢迎提供更好的、更快、更简洁的代码或者方法和指出错误。在ubuntu12.04使用gcc4.6.3版本编译,在vc中如出现错误,请谅解。)

/*
*created by Reage at 2012 November 29
*description: 稀疏矩阵实现,包含乘法、逆转
*
*blog:http://blog.csdn.net/rentiansheng
*/
#include <stdio.h>
#include <stdlib.h>

#define LINE print_split(20)

typedef struct triple{
	int i,j;//行列
	int value;
}triple; 

typedef struct matrix{ 
	triple * head;
	int row,column,count;//矩阵的行、列、稀疏矩阵的元素个数
}matrix; 

/* 
*description:判断某一个位置是否已经存在元素
*parameter:
*	x:行坐标
*	y:列坐标
*	count:要查找的元素个数,如果为0表示全部,否则是count的值
*result:找到返回1,未找到返回0
*/
int find_ item (matrix *m, int x, int y, int count ){
	triple *tp = m->head;
	if ( !count || count > m->count ) count =m->count;
	int i;
	for (i  = 0; i < count - 1; i++){
		if ( tp->i == x && tp->j == y) return 1; 
		tp++;
	}
	return 0;
}

/*
*初始化稀疏矩阵
*/
void  init_matrix (matrix *m, int row, int column, int count){
//	if (m->head) free(m->head);//如果矩阵已经存在,释放原有的数据空间
	m->head = (triple *) malloc ( count * sizeof (triple));
	if (!m->head){
		printf("Allocate memory failed!application will exit.");
		exit(0);
	}
	m->row = row;
	m->column = column;
	m->count = count;

} 

/*
*输入的稀疏矩阵的可能没有按照指定的排列顺序,用此来整理
*首先按行从小到大,当行等时候按列从小到大
*/
void sort_matrix (matrix *m){
	int i, j, count = m->count;
	int loc;
	triple * tp = m->head;
	triple tmp;
	for ( i = 0; i < count-1; i++){
		loc = i;
		for (j = i+1; j < count; j++){
			if ( tp[loc].i > tp[j].i){//按行排序
				loc = j;
			}
			else if (tp[loc].i == tp[j].i && tp[loc].j > tp[j].j){
				loc = j;
			}
		}
		memcpy (&tmp, &tp[loc], sizeof(triple));
		memcpy (&tp[loc], &tp[i], sizeof(triple));
		memcpy (&tp[i], &tmp, sizeof(triple));
	}
}

/*
*创建一个使用数组存储的稀疏矩阵
*/
void creat_matrix (matrix *m){
	int row,column,count;//存储稀疏矩阵的行、列、非零元素的个数
	int i;
	int x,y;
	triple * use_triple;
	int value;
	printf ("please enter sparse matrix row,column:\n");
	scanf ("%d%d", &row, &column);
	printf ("please enter a number as the number of non-zero elements of the sparse matrix:\n");
	scanf ("%d", &count);
	init_matrix (m, row, column, count);
	use_triple = m->head;
	for (i = 0; i < count; i++){
		repeat:printf ("please enter  %d elements x and y coordinate values:", i+1);
		printf ("and a number as  element  value:");
		scanf ("%d%d%d", &x, &y, &value);
		if ( find_item (m, x, y, i+1) ) {printf("The position has been there exists an elemetn.\n");goto repeat;}
		use_triple->i = x;
		use_triple->j = y;
		use_triple->value = value;
		use_triple ++;
 	}
	sort_matrix (m);
} 

/*
*起到分割符的作用,输出count个‘—’符号
*/
void print_split (int count){
	int i;
	for (i = 0; i < count; i++)
			printf("-");
	printf("\n");
}

/*
*数据稀疏矩阵中的内容
*/
void print_matrix (matrix m){
	int len = m.count;
	int i;
	printf("\n");
	triple * sm = m.head;
	LINE;
	for (i = 0; i < len; i++){
		printf("%4d | %4d | %d\n", sm->i, sm->j, sm->value);
		sm++;
		LINE;
	}
}

/*
*description: 对稀疏矩阵逆转了,想将矩阵逆转,然后进行排序。
*paramtere:
*	sm:源稀疏矩阵
*	dm:目的稀疏矩阵
*/
void transpose_matrix1 (matrix *sm, matrix *dm){
	int i, j, count = sm->count;
	triple *dt, *st = sm->head;
	init_matrix (dm, sm->row, sm->column, sm->count);//对目的稀疏矩阵进行初始化。
	dt = dm->head
	;for (i = 0; i < count; i++){
		dt->i = st->j;
		dt->j = st->i;
		dt->value = st->value;
		sm++;
		dt++;
	}
	sort_matrix (dm);
 	
} 

/*
*description: 对稀疏矩阵逆转了,
*paramtere:
*	sm:源稀疏矩阵
*	dm:目的稀疏矩阵
*/
void transpose_matrix (matrix *sm, matrix *dm){
	int i, j;
	triple *dt, *st;
	init_matrix (dm, sm->row, sm->column, sm->count);//对目的稀疏矩阵进行初始化。
	dt = dm->head;
	for (i = 0; i < sm->column; i++){
		st = sm->head;
		for (j = 0; j < sm->count; j++){
				if ( st->j == i){
					dt->i = i;
					dt->j = st->i;
					dt->value = st->value;
					dt++;
				}
			st++; 
		}
	}

}

/*
*description:向稀疏矩阵中插入一个元素,将元素个数加一
*parameter:
*	i,j,value:要插入元素位置的行、列、值
*/
void insert_matrix (matrix *m, int i, int j, int value){
	m->count++;
	if(1 ==  m->count)
		m->head = (triple *) malloc (sizeof(triple));
	else
		m->head = (triple *) realloc (m->head, m->count * sizeof(triple));
	(m->head)[m->count-1].i = i;
	(m->head)[m->count-1].j = j;
	(m->head)[m->count-1].value = value;
}


/*
*description:矩阵的乘法
*pararmeter:
*	m1,m2:乘数和被乘数
*	result:成绩结果
*/
void multi_matrix (matrix *m1, matrix *m2, matrix *result){
	int tmp ; //保存临时计算的结果
	int i, j; //i表示计算到m2矩阵的第几列了。
	int use = 0; //表示m1正在计算当前行的第几个非零位置
	triple *tp = m1->head;//m1中非零元素的首地址
	triple *tp2 = m2->head;//m2中非零元素的首地址
	init_matrix (result, 0, 0, 0);//初始化矩阵
	if (m1->column != m2->row) return ;//无法做运算的,不满组运算条件
	if ( m1->column > m1->count || m2->row > m2->count){
		//有矩阵的成绩关系可以知,m1中的一行与m2中的一列做运算。
		//如果m1中的非零个数不满足一行,m2中的非零个数不满足一列。没有做运算的必要
		return ;
	}
	/*
	*1.首先找本行中的一个m1中非零元素tp[usue],
	*2.查找m2[tp[use].j][i]元素是否存,存在转到第3步,否则转到第4步
	*3.计算两者的成绩加入到到tmp中。
	*4.查找同行的下一个非零元素。如存在转到第2不,不存在转到第5步
	*5.清空临时数据,进入下一个行,转到第1步。
	*/
	while ( tp < &tp[m1->count] ){//判断m1中是否还有未计算的元素,没有的话,计算结束
		for (i = 0; i < m2->column; i++){//用来控制与m2中的第几列做运算
			use = 0;//计算本行中的第一个非零元素
			tmp = 0;//计算的结果
			for (j = 0; j < m2->count; j++){//遍历m2中的所有元素,差找目标元素
				if(tp2[j].j == i && tp2[j].i == tp[use].j ){
					tmp += tp2[j].value * tp[use].value;
					if( tp[use].j == m1->column){
						break;
					} 
					if (tp >= &((m1->head)[m1->count]) || tp[use].i != tp[use+1].i ) break;
					use ++;
				}
			}
			if (tmp > 0) insert_matrix (result ,i ,j ,tmp);
		}
		//转到下一行
		while ( tp->i == tp[1].i){
			tp++;
			if ( tp >= &((m1->head)[m1->count]) ) return ;
		}
		tp++;
	}
}

void destroy_matrix (matrix *m){
	m->row = 0;
	m->column = 0;
	m->count = 0;
	free (m->head);
}


你可能感兴趣的:(数据结构,c,稀疏矩阵)