使用C语言实现矩阵转置(稀疏矩阵)

article/2025/9/23 3:37:31

目录

1.转置矩阵(普通矩阵)

2.转置矩阵(稀疏矩阵)

(1)稀疏矩阵

(2)稀疏矩阵的压缩存储方式

(3)理论运算方法


1.转置矩阵(普通矩阵)

矩阵的转置:根据主对角元素作为对称轴进行元素的互换。转置运算是一种最简单的矩阵运算。对一个mxn的矩阵M进行转置得到矩阵T(nxm),且T(i,j)=M(j,i),1<=i<=n,1<=j<=m.

注:虽然矩阵的转置非常的简单,但是对于其在计算机上的时间复杂度也是做了很多的优化,特别是对稀疏矩阵的转置,因为稀疏矩阵的存储方式不是直接使用nxn的方式进行存储的,而是采用其他的方式:如三元组等。

#include<stdlib.h>
#include<stdio.h>#define Mat_n 5typedef int ElemType;int M[Mat_n][Mat_n];
//矩阵的转置
void TransposeMatrix(int N[Mat_n][Mat_n],int n,int m){for(int col=1;col<=m;col++){for(int row=1;row<=n;row++){M[col][row]=N[row][col];}}
} int main(){int n,m; int N[Mat_n][Mat_n];printf("请输入矩阵(方阵)行和列: ");scanf("%d %d",&n,&m);//初始化for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){N[i][j]=M[i][j]=0; }}printf("请输入矩阵(方阵):\n");for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){scanf("%d",&N[i][j]); }}TransposeMatrix(N,n,m);for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){printf("%d  ",M[i][j]);}printf("\n");}return 0;
}/*
4 4
1  2  0  3
5  6  3  8
12 23 45 67
9  5  3  5
*/

2.转置矩阵(稀疏矩阵)

(1)稀疏矩阵

(2)稀疏矩阵的压缩存储方式

由于是稀疏矩阵,所以只需要存储非零元即可,非零元的位置为(i,j),所以采用三元组的形式(i,j,aij)唯一确定矩阵A的非零元。

比如:((1,2,2),(1,3,9),(3,1,3),(3,6,4),(4,3,2),(5,2,8),(6,1,5),(6,4,7))

(3)理论运算方法

假设M矩阵的三元组形式如下:

M.data

元素

1

2

12

1

3

9

3

1

-3

3

6

14

4

3

24

5

2

18

6

1

15

6

1

-7

转置之后的T矩阵三元组如下:

T.data

元素

1

3

-1

1

6

15

2

1

12

2

5

18

2

1

9

2

4

24

4

6

-7

6

3

14

步骤:

      第一步:将矩阵的行列值进行互换;

      第二步:将每个元组中的i和j值进行调换;

      第三步:重排三元组之间的次序即可实现矩阵的转置;

而对于第三步的具体实现步骤:

      方法一:

按照T.data中的三元组的次序依次在M.data中找到相应的三元组进行转置。也就是说对其M.data中的三元组表进行扫描一遍(从第一行到最后一行),由于M.data是以行序为主序来存放每个非零元的,所以也可以得到T.data应有的次序。

#include<stdlib.h>
#include<stdio.h>#define MAXSIZE 10typedef int ElemType;typedef struct {int i,j;ElemType e;
}Triple;typedef struct {Triple data[MAXSIZE];int mu,nu,tu;//矩阵的行,列和非零元个数 
}TSMatrix; void TransposeSMatrix(TSMatrix M,TSMatrix&T){//矩阵的行列互换 T.mu=M.nu;T.nu=M.mu;T.tu=M.tu;if(T.tu){int q=1;for(int col=1;col<=M.nu;col++){for(int p=1;p<=M.tu;p++){if(M.data[p].j==col){T.data[q].i=M.data[p].j;T.data[q].j=M.data[p].i;T.data[q].e=M.data[p].e;q++;}}}}
}int main(){TSMatrix M,T;printf("请输入矩阵的行,列和非零元数: \n");scanf("%d %d %d",&M.mu,&M.nu,&M.tu);printf("请输入矩阵(三元组): \n");for(int i=1;i<=M.tu;i++){scanf("%d %d %d",&M.data[i].i,&M.data[i].j,&M.data[i].e);}printf("----------------------------------------------\n");TransposeSMatrix(M,T);printf("转置矩阵T: \n");for(int i=1;i<=T.tu;i++){printf("%d %d %d\n",T.data[i].i,T.data[i].j,T.data[i].e);}return 0;
}
/*
6 6 81 2 12 
1 3 9
3 1 -3
3 6 14
4 3  24
5 2 18
6 1 15
6 4 -7
*/

 注:但是方法一从时间复杂度上来说:O(nu x tu),所以和非零元的个数是成正比的;普通的矩阵的转置时间复杂度为O(mu x nu);但是对于方法一来说,当tu的数量级和nu x mu相同时,就会出现时间复杂度为O(mu x nu x nu),所以这个时候比普通的方法还要耗时。因此方法二对其进行了改进。

方法二:

假设:如果能够预先确定矩阵M中的每一列(也就是转置之后的矩阵中的每一行)的第一个非零元在T.data中的应有位置,那么在对M.data中的三元组依次做转置时,便可直接放到T.data中恰当的位置。

为了提前确定位置,首先需要设置两个数组变量:num和cpot。

其中num[col]表示矩阵M中的第col列中非零元的个数,cpot[col]表示M中第col列的第一个非零元在T.data中的恰当位置。

矩阵M的数组cpot的值
col1234567
num[co]2221010
cpot[col]1357889

num[co]更加形象的计算方式:

#include<stdlib.h>
#include<stdio.h>#define MAXSIZE 10const int maxn=100;typedef int ElemType;typedef struct {int i,j;ElemType e;
}Triple;typedef struct {Triple data[MAXSIZE];int mu,nu,tu;//矩阵的行,列和非零元个数 
}TSMatrix; void TransposeSMatrix_1(TSMatrix M,TSMatrix&T){//矩阵的行列互换 T.mu=M.nu;T.nu=M.mu;T.tu=M.tu;int num[100];int cpot[100];if(T.tu){//初始化for(int col=1;col<=M.nu;col++){num[col]=0;}for(int t=1;t<=M.tu;t++){++num[M.data[t].j];}cpot[1]=1;for(int col=2;col<=M.nu;col++){cpot[col]=cpot[col-1]+num[col-1];}for(int p=1;p<=M.tu;p++){int col=M.data[p].j;//提前得到在T.data中第q行int q=cpot[col];T.data[q].i=M.data[p].j;T.data[q].j=M.data[p].i;T.data[q].e=M.data[p].e;//这里之所以要加就是因为一行有多个元素++cpot[col];}}
}int main(){TSMatrix M,T;printf("请输入矩阵的行,列和非零元数: \n");scanf("%d %d %d",&M.mu,&M.nu,&M.tu);printf("请输入矩阵(三元组): \n");for(int i=1;i<=M.tu;i++){scanf("%d %d %d",&M.data[i].i,&M.data[i].j,&M.data[i].e);}printf("----------------------------------------------\n");TransposeSMatrix_1(M,T);printf("转置矩阵T: \n");for(int i=1;i<=T.tu;i++){printf("%d %d %d\n",T.data[i].i,T.data[i].j,T.data[i].e);}return 0;
}
/*
6 6 81 2 12 
1 3 9
3 1 -3
3 6 14
4 3  24
5 2 18
6 1 15
6 4 -7
*/

注:方法二比之前多用了两个辅助的数组空间num和cpot,但是从时间上来看的话,时间复杂度为O(nu+tu),如果tu的数量级和nu x mu同等,时间复杂度为O(nu x mu).

 参考书籍《数据结构》(清华大学版)


http://chatgpt.dhexx.cn/article/sOx4hVYZ.shtml

相关文章

c语言矩阵

思路&#xff1a;开辟一个新的同样规格的矩阵b&#xff0c;并将其全部置1. 遍历矩阵a(原矩阵)&#xff0c;发现有0的就在b的此行此列中插入0 // // main.c // test // // Created by 神威 on 2018/9/11. // Copyright © 2018年 神威. All rights reserved. // #incl…

C语言-矩阵转置

描述 KiKi有一个矩阵&#xff0c;他想知道转置后的矩阵&#xff08;将矩阵的行列互换得到的新矩阵称为转置矩阵&#xff09;&#xff0c;请编程帮他解答。 输入描述&#xff1a; 第一行包含两个整数n和m&#xff0c;表示一个矩阵包含n行m列&#xff0c;用空格分隔。 (1≤n≤…

C语言对矩阵进行转置

对矩阵进行转置最重要的是值的交换&#xff0c;这里用到了二重数组 #include <stdio.h> #include <stdlib.h>int main() {int a[3][3]{1,2,3,4,5,6,7,8,9};//初始化一个矩阵出来int b[3][3]{0};for(int i0;i<2;i){for(int k0;k<2;k){b[k][i]a[i][k];//对矩…

C语言 - 矩阵转置

C语言 - 矩阵转置 输入NM的矩阵&#xff0c;输出它的转置矩阵。 Input 第一行为整数N&#xff0c;M&#xff08;1≤N&#xff0c;M≤100&#xff09;。 接着是一个NM的矩阵。 Output 转置矩阵。 Example Input 2 3 1 2 3 4 5 6 Example Output 1 4 2 5 3 6#include&l…

(C语言)求矩阵各行元素之和

本题来自pintia.cn 题目要求代码测试结果图PTA测试结果 题目要求 本题要求编写程序&#xff0c;求一个给定的mn矩阵各行元素之和。 输入格式&#xff1a; 输入第一行给出两个正整数m和n&#xff08;1≤m,n≤6&#xff09;。随后m行&#xff0c;每行给出n个整数&#xff0c;其间…

编写矩阵运算程序(C语言)

编写矩阵运算程序之C语言 1. 要求2 代码 1. 要求 a) 功能包括&#xff1a;矩阵加、矩阵减、矩阵乘、矩阵三角化 b) 实现方式1&#xff1a;函数的参数为&#xff1a;二维数组名、行数、列数 2 代码 #include<stdio.h> #define M 20 #define N 20 float A[M][N]; float…

C语言——矩阵转置

矩阵转置的原理&#xff1a;行元素变成列元素&#xff0c;列元素变成行元素 例如&#xff1a; 矩阵转置代码 #include<stdio.h> #include<malloc.h> #include<stdlib.h> #include<math.h>//矩阵转置 double** Matrix_T(double** arr) {if(arrNULL)e…

C语言实现矩阵的乘法

矩阵乘法作为算法题我觉得对我来说是比较难想的&#xff0c;而且作为没学线性代数的我来说&#xff0c;这简直就是场灾难&#xff0c;在我研究了书上及网上的有关资料后&#xff0c;我觉得自己应该差不多可以理解矩阵乘法的要领了&#xff0c;希望可以帮助大家&#xff1a;其实…

C语言矩阵运算

矩阵的乘法&#xff1a; 矩阵的列数&#xff08;column&#xff09;和第二个矩阵的行数&#xff08;row&#xff09;相同时 #include<stdio.h>int main() { int a[2][4], b[4][3], c[2][3];int i, j, k, sum; printf("输入一个24的矩阵&#xff1a;\n"); fo…

c语言矩阵的乘法

矩阵的乘法&#xff1a; 两个矩阵只有在第一个矩阵的列数&#xff08;column&#xff09;和第二个矩阵的行数&#xff08;row&#xff09;相同时才有意义。一般单指矩阵乘积时&#xff0c;指的便是一般矩阵乘积。一个mn的矩阵就是mn个数排成m行n列的一个数阵。 运算规则&#x…

C语言刷题小结---矩阵篇

电影黑客帝国有很多这样的场景 用矩阵表示我们看到的一切&#xff01; 而在编程中矩阵是用数组来表示的 目前小作者还只是学习编程的初学者&#xff0c;很多知识内容都还没有学习。但相信每一个学习编程的小伙伴在做C语言方面的练习时都会遇到有关矩阵相关的题目&#xff0c;…

《C语言》矩阵问题

一.矩阵乘法 1.定理&#xff1a; 两个矩阵的乘法仅当第一个矩阵A的列数和另一个矩阵B的行数相等时才能定义。如A是mn矩阵和B是np矩阵&#xff0c;它们的乘积C是一个mp矩阵。 例如&#xff1a; 2.思路 1. i&#xff0c;j分别代表行和列&#xff0c;所以应该定义一个二维矩阵&…

C语言矩阵乘法

本篇内容 1&#xff09;首先介绍了矩阵乘法的基本原理&#xff1b; 2&#xff09;然后介绍了相对初阶的C语言乘法代码设计&#xff1b; 3&#xff09;最后根据C语言动态内存规划&#xff0c;提出了更加便捷、优化的代码设计&#xff0c;希望能给大家带来帮助。 更新&#xff1a…

c语言之矩阵

矩阵作为线性代数核心内容之一也是刷题人时常会遇到的一种类型。本篇博客简单介绍一下矩阵转置、上三角矩阵以及杨氏矩阵。 1.转置矩阵&#xff1a;输入m行n列的矩阵以n行m列的方式打印出来。只要将数组的行列进行交换即可&#xff0c;并不难想也不难写.&#xff08;相应练习&a…

vue-quill-editor 使用-图片上传

vue 项目开发中&#xff0c;文本编辑器的选择很多&#xff0c;一些熟悉的文本编辑器都可以使用&#xff0c;如UEditor、wangEditor&#xff0c;这里介绍基于 vue 的一个文本编辑器插件 vue-quill-editor 此插件基于 quill&#xff0c;所以使用 cdn 节点方式引用时&#xff0c;…

Error: Cannot find module ‘./XXX.jpg‘ 问题解决 Vue动态显示图片

刚开始学习Vue 在循环输出图片时&#xff0c;浏览器报错Error: Cannot find module ‘./tqwl.jpg’ 这张图片是放在本地文件夹内的 这是图片的展示代码 <el-table-column label"展示" width"180"><template slot-scope"scope"><…

解决js中获取不到图片路径的情况

在写一个todoList作品时&#xff0c;需要点击事件更改图片路径时&#xff0c;遇到了获取不到图片路径的情况 在html中用src“”来获取的图片&#xff0c;凭主观臆想觉得在js中判断它的路径时&#xff0c;没有作用&#xff0c;控制台中显示的不是我们熟悉的路径格式 查阅得知&a…

vue-quill-editor删除服务器多余图片

这几天在做富文本编辑业务&#xff0c;在删除服务器资源方面遇到了问题&#xff0c;网上搜索了很久都没找到办法&#xff0c;现在把自己解决的过程记录如下&#xff1a;思路&#xff1a; 点击工具栏的图标&#xff0c;选取图片&#xff08;不是base64格式&#xff09;上传到服…

将JS代码隐藏在图片中的方法

之前写过利用图片重写的方法清除图片中恶意代码的文章&#xff0c;java清除恶意代码 &#xff0c;但这些图片中的恶意代码是怎么植入进去的呢&#xff0c;有简便方法&#xff0c;也有复杂方法。先来看如下这张图片&#xff0c;是Google的LOGO&#xff0c;是一张完全正常的png图…