稀疏矩阵(三元组)的创建,转置,遍历,加法,减法,乘法。C实现

一、思路。

1.创建。

可以直接赋值字符串,但是为0的元素也要依次赋值,比较麻烦,但是容易理解也能实现。

其次也可以构思三元组赋值,只赋值非零元素和它的行,列数,在打印时进行if判断,没有赋值的就输出0,这样比较简单。

创建结构体时,一个矩阵需要有它的行总数和列总数,并且针对三元组,你还需要每个元素所在的行和列,还有这个三元组的非零元素总和。

2.遍历。

对于三元组,它包括非零元素集合和零元素集合,针对于非零元素的行,列数,进行双重for循环,如果非零元素的行,列数与for循环中的变量相等,就输出这个数的值,否则就输出0。

3.转置。

转置就是把行号和列号互换,如果按行先序的话,时间复杂度过高,所以一般都采用列先序。

  • 首先进行 行总数,列总数,以及非零元素总数的赋值。
  • 其次进行按列循环对非零元素的遍历
  • 如果非零元素的列号==外面循环的列号,则进行行,列号的互换。

快速转置法的详解图有点复杂,所以没做,但是代码在下面有,并且运行正常。

4.加法,减法,乘法。

加法非常简单,在A,B两个矩阵中,如果非零元素的位置相同,则新矩阵C这个位置的值就=A,B的值相加,如果不相同则矩阵C的值就等于A的值或者B的值。

减法就是加上矩阵*-1

  乘法如果相等就相乘,不相等就不用管,因为就算管了最后也为0;

二、具体代码。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
#define false 0
#define true 1
#define max 100
typedef struct {
	int value;    //value为具体数值 
	int row,col;  //row为行,col为列 
}Array;
typedef struct {
	Array data[max+1];    
	int rows,cols,nums;   //nums为非零元素个数 
}Arrays;
//创建稀疏矩阵 
int InitArray(Arrays *L,int rows,int cols,int nums){
	int i,j;
	L->nums=nums;
	L->cols=cols;
	L->rows=rows;
	assert(L->nums<max);
	printf("-------------\n");
	printf("请依次输入非零元素的行数,列数,值:\n");
	for (int i = 1; i <= L->nums; i++) {
		scanf("%d %d %d", &L->data[i].row, &L->data[i].col, &L->data[i].value);
		}
		printf("创建成功!\n");
		return true;
	}
//遍历输出稀疏矩阵  三元组形式
void bianli1(Arrays *L) {
	printf("-------------三元组形式形式遍历输出:\n");
	for (int i = 1; i <= L->rows; i++) {
		printf("%d行%d列%d \n",L->data[i].row,L->data[i].col,L->data[i].value);
	}
}

//遍历输出稀疏矩阵  矩阵形式
void bianli2(Arrays *L) {
	int flag = 1;         //flag代表 
	for (int i = 1; i <= L->rows; i++) {
		for (int j = 1; j <=L->cols; j++) {
			if (L->data[flag].value!=0&&L->data[flag].row==i&&L->data[flag].col==j) {
				printf(" %d", L->data[flag].value);
				flag++;
			}
			else {
				printf(" 0");
			}
		}
		printf("\n");
	}
}
//矩阵普通转置(按列)
int Transform(Arrays a,Arrays *b){   // //a为原矩阵,b为转置后的矩阵
	b->cols=a.cols;
	b->nums=a.nums;
	b->rows=a.rows;
	if(b->nums>0){
		int j=1;
		for(int k=1;k<=a.cols;k++){
			for(int i=1;i<=a.nums;i++){    //进入非零元素循环 
				if(a.data[i].col==k){      //如果在每一个列中有非零元素,则进行转置操作 
					b->data[j].row=a.data[i].col;    //j代表表B的非零元素个数值,它从1开始。 
					b->data[j].col=a.data[i].row;
					b->data[j].value=a.data[i].value;
					j++;
					if(j>a.nums) return false;
				}
			} 
		}
	}
} 
//矩阵快速转置
void FastTransform(Arrays *a,Arrays *b){   //a为原矩阵,b为转置后的矩阵 
	int num[max],position[max];
	int col,i,k,m;
	b->cols=a->cols;
	b->nums=a->nums;
	b->rows=a->rows;
	if(b->nums>0){
		for(col=1;col<=a->cols;col++){   //首先将num数组的数值都赋值为0 
			num[col]=0;
		}
		for(i=1;i<=a->nums;i++){   //再遍历非零元素,把非零元素的列所在的num数组进行++操作 
			num[a->data[i].col]++;
		} 
		position[1]=1;     //第一个非零元素的position值定义为1 
	 	for(col=2;col<=a->cols;col++){
		position[col]=position[col-1]+num[col-1];   //前一列非零元素的起始位置加非零元素的个数等于后一列的起始位置 
		}
		for(k=1;k<=a->nums;k++){   //对非零元素进行遍历并依次转置 
			col=a->data[k].col; 
			m=position[col];
			b->data[m].row=a->data[k].col;
			b->data[m].col=a->data[k].row;
			b->data[m].value=a->data[k].value;
			position[col]++;
		} 
	}
} 
//矩阵加法
int ADD(Arrays a,Arrays b,Arrays *c){
	int k=1,i,j;      //i为a的元素数目,j为b的元素数目,k为c的元素数目 
	
	//同行同列的才能相加 
	if(a.cols!=b.cols||a.rows!=b.rows){
		return false;
	}
	
	c->cols=a.cols;   //赋值总行数,总列数 
	c->rows=a.rows;
	//进行遍历赋值 
	for(i=1,j=1;i<=a.nums&&j<=b.nums;){
	   
	   //B的行号大于A直接将A中元素加入C矩阵 
		if(a.data[i].row<b.data[j].row){
			c->data[k].col=a.data[i].col;
			c->data[k].row=a.data[i].row;
			c->data[k].value=a.data[i].value;
			k++;       //C元素向后增一位 
			i++;       //a赋值则a元素向后增一位,如果时b则b元素向后增一位 
		}
		//B的行号小于A直接将B中元素加入C矩阵
		else if(a.data[i].row>b.data[j].row){
			c->data[k].col=b.data[j].col;
			c->data[k].row=b.data[j].row;
			c->data[k].value=b.data[j].value;
			k++;
			j++; 
		}else{  //行号相同 
			
			//B的列号小于A直接将B中元素加入C矩阵
			if(a.data[i].col>b.data[j].col) {
			c->data[k].col=b.data[j].col;
			c->data[k].row=b.data[j].row;
			c->data[k].value=b.data[j].value;
			k++;
			j++;
			}
			
			//B的列号大于A直接将A中元素加入C矩
			else if(a.data[i].col<b.data[j].col){
			c->data[k].col=a.data[i].col;
			c->data[k].row=a.data[i].row;
			c->data[k].value=a.data[i].value;
			k++;
			i++;
			}
			//相等 
			else {
				 
				c->data[k].col=a.data[i].col;
				c->data[k].row=a.data[i].row;
				c->data[k].value=a.data[i].value+b.data[j].value;
				k++;
				i++;
				j++;
			}
		}
	}
	while(i<=a.nums){ //B取完A未取完
	
			//将A中所剩元素依次加入到C中
		c->data[k].col=a.data[i].col;
		c->data[k].row=a.data[i].row;
		c->data[k].value=a.data[i].value;
		k++;
		i++;
	}   
	while(j<=b.nums){  //A取完B未取完
			
			//将A中所剩元素依次加入到C中
		c->data[k].col=b.data[j].col;
		c->data[k].row=b.data[j].row;
		c->data[k].value=b.data[j].value;
		k++;
		j++;
	}
}
    
			


//矩阵减法
int reduce(Arrays a,Arrays b,Arrays *c){   //调用加法操作,在b矩阵基础上乘 -1 在加 a矩阵 
	for(int i=1;i<=b.nums;i++){
		b.data[i].value=b.data[i].value*-1;
	}
	ADD(a,b,c);
} 
//矩阵乘法
int multipe(Arrays a,Arrays b,Arrays *c){
	int m=1,n=1,k=1;      //m为a的元素数目,n为b的元素数目,k为c的元素数目 
	if(a.cols!=b.cols||a.rows!=b.rows){
		return false;
	}
	c->cols=a.cols;
	c->rows=a.rows;
	while(m<=a.nums&&n<=b.nums){
		if(a.data[m].col==b.data[n].col&&a.data[m].row==b.data[n].row){
			c->data[k].col=a.data[m].col;
			c->data[k].row=a.data[m].row;
			c->data[k].value=a.data[m].value*b.data[n].value;
		}
		m++;n++;k++;
	}
} 
int main(){
	Arrays s;
	Arrays s1;
	Arrays s2;
	Arrays s3;
	int row, col, num;
	//创建
	printf("请依次输入稀疏矩阵A的行数,列数,非零元个数(用空格隔开):\n");
	scanf("%d %d %d", &row, &col, &num);
	InitArray(&s,row,col,num);
	bianli2(&s);
	printf("请依次输入稀疏矩阵B的行数,列数,非零元个数(用空格隔开):\n");
	scanf("%d %d %d", &row, &col, &num);
	InitArray(&s1,row,col,num);
	bianli2(&s1);
	printf("---------矩阵B的转置为:\n");
	Transform(s1,&s3);
	bianli2(&s3);
	printf("---------矩阵相乘为:\n"); 
	multipe(s,s1,&s2);
	bianli2(&s2);
	printf("---------矩阵相加为:\n"); 
	ADD(s,s1,&s2);
	bianli2(&s2);
	printf("---------矩阵相减为:\n");
	reduce(s,s1,&s2); 
	bianli2(&s2);
}

三、实现结果。

 

 

  • 31
    点赞
  • 136
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
以下是用 Python 语言实现三元组减法的代码: ```python class Triple: def __init__(self, i, j, v): self.i = i self.j = j self.v = v def sparse_matrix_sub(A, B): # 初始化结果矩阵C C = [] # 初始化指针 i = j = 0 # 循环遍历A和B矩阵三元组 while i < len(A) and j < len(B): if A[i].i == B[j].i and A[i].j == B[j].j: # 如果A和B的当前三元组在同一个位置,计算差值 diff = A[i].v - B[j].v if diff != 0: # 如果差值不为0,则将结果添加到C中 C.append(Triple(A[i].i, A[i].j, diff)) i += 1 j += 1 elif A[i].i < B[j].i or (A[i].i == B[j].i and A[i].j < B[j].j): # 如果A的当前三元组在B的当前三元组之前,将A的当前三元组添加到C中 C.append(A[i]) i += 1 else: # 如果B的当前三元组在A的当前三元组之前,将B的当前三元组取相反数,添加到C中 C.append(Triple(B[j].i, B[j].j, -B[j].v)) j += 1 # 将A或B中剩余的三元组添加到C中 while i < len(A): C.append(A[i]) i += 1 while j < len(B): C.append(Triple(B[j].i, B[j].j, -B[j].v)) j += 1 return C ``` 调用该函数即可进行稀疏矩阵减法的运算,例如: ```python # 初始化两个稀疏矩阵A和B A = [Triple(0, 1, 2), Triple(1, 0, 3), Triple(1, 2, 4)] B = [Triple(0, 1, 1), Triple(0, 2, 2), Triple(1, 0, 3)] # 进行矩阵减法运算 C = sparse_matrix_sub(A, B) # 输出结果矩阵C for triple in C: print("({},{},{})".format(triple.i, triple.j, triple.v)) ``` 输出结果为: ``` (0,1,1) (0,2,-2) (1,0,0) (1,2,4) ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

犀牛超人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值