矩阵的转置

article/2025/10/4 12:53:10

稀疏矩阵:

当一个矩阵中的很多元素都是零,而且非零元素的分布没有规律时,该矩阵称为稀疏矩阵。

稀疏矩阵的压缩存储方法:

从稀疏矩阵的概念,我们可以知道,稀疏矩阵的大多元素都是零。所以,我们只需要存储非零元素即可。这时,我们引入三元组表的概念:三元组表是一个线性表,线性表中的每一个结点对应稀疏矩阵的一个非零元素。结点包括三个域,分别为非零元素的行下标、列下标和值。并且,结点按矩阵的行优先顺序排列。

【例】存在矩阵A。那么矩阵A是怎么存储的呢?


A矩阵的三元组表:索引为0时,存储的是稀疏矩阵的行数、列数和非零元素的个数。

索引

i

j

v

0

5

6

6

1

1

1

3

2

1

6

7

3

2

3

6

4

3

1

2

5

3

2

3

6

5

5

2

表中结点类型定义如下:(JAVA

package com.linearList.matrix;
/*
*  说明: 三元组的结点描述 
*  @author 秦霞爱朱剑锋
*/
public class Node {
int i;            // 行下标
int j;            // 列下标
int value;        // 值
public Node() {}
public Node(int i, int j, int vlaue) {
this.i = i;
this.j = j;
this.value = vlaue;
}
}

矩阵类型定义如下:

package com.linearList.matrix;
/**  说明:矩阵的压缩存储描述(行优先)*/
public class Matrix {final int MAX = 10;			// 非零元素个数的最大值int rows, cols, vals;				// 分别为行、列、非零元素个数Node data[] = new Node[MAX];public Matrix(int rows, int cols, int vals) {this.rows = rows;this.cols = cols;this.vals = vals;// 初始化data[0]:data[0]的i,j,v分别存储稀疏矩阵的行数、列数和非零元素的个数data[0] = new Node(rows, cols, vals);// 申请剩余空间if(vals <= MAX) {for (int i = 1; i <= vals; i++) {data[i] = new Node();}}}
}

矩阵的转置运算:
          
A的三元组表

索引

i

j

v

0

5

6

6

1

1

1

3

2

1

6

7

3

2

3

6

4

3

1

2

5

3

2

3

6

5

5

2


B的三元组表

索引

i

j

v

0

5

6

6

1

1

1

3

2

1

6

7

3

2

3

6

4

3

1

2

5

3

2

3

6

5

5

2

也就是说,矩阵的转置实际上是三元组表的改变。

【算法一】

算法思路:

①将两个矩阵的行数和列数相互交换;

②将每个三元组中的ij互相调换;

③重排三元组之间的次序。

代码实现:(JAVA

// 稀疏矩阵的转置
public static Matrix transpose(Matrix a) {
Matrix b = new Matrix(a.cols, a.rows, a.vals);        // 转置后的矩阵b
int bindex = 1;
for(int col = 1; col <= a.cols; col++) {        // 按a的列序转置
for(int aindex = 1; aindex <= a.vals; aindex++) {    // 扫描整个三元组表
if(a.data[aindex].j == col) {
b.data[bindex].i = a.data[aindex].j;
b.data[bindex].j = a.data[aindex].i;
b.data[bindex].value = a.data[aindex].value;
bindex++;
}
}
}
return b;
}

核心代码讲解:

①我们遍历矩阵a的列序,保证转置之后的矩阵行优先的原则。

②扫描整个三元组,找到当前列的结点。(此时,浪费了一定的时间。因为对于每一个col,我们都需要遍历整个三元组,直到与其对应的为止。)

算法评价:

上述算法是在二重循环内完成的,算法的时间复杂度为O(cols*vals)。当非零元素的个数值vals=cols*rows时,时间复杂度为O()。可见,该算法虽然节省了空间,但时间复杂度提高了。所以,上述算法只适用于当vals<<rows*cols(非零元素较少)的情况。

算法二:快速转置算法】

原理:

我们已经知道,矩阵的转置实际上是改变其对应的三元组。那么,我们事先能不能知道改变之后的三元组是什么样子呢?答案是肯定的。进一步,既然我们已经知道了转置之后的三元组,那么对于索引为1的第一个非零元素,我们可不可以直接确定它转置之后再哪一个位置呢?同理,索引为2的第二个非零元素,我们能不能直接确定它转置之后的位置呢?以此类推,如果我们知道了这样一个映射关系,我们就可以做到直接定位,把结点插入到新的位置。

举个例子:

我们去图书馆找书的时候,我们不会从图书馆的第一个书架开始,一本一本的去找。我们是怎么做的呢?根据书的编号,参考图书馆存放书的信息,直接定位到相应的书架去找!那么,在这个例子中,图书馆为大家提供的馆藏信息表(记录不同的书的存放位置)就显的很重要了。这个表,实际上就是一个映射关系。

那么,如果我们也构建这样一个映射关系表,是不是也可以做到直接定位了呢?答案是肯定的。

如何构建这样一个映射关系?

第一列的元素转置之后在第一行。那么如果第一列的非零元素有两个,那么他们肯定占据的是索引12位置。同理,第二列的非零元素如果有两个,占据的应该是索引34位置。以此类推,我们便可以确定转置之后的位置了。因此,我们需要记录:每一列非零元素的个数num[col]以及该列第一个非零元素的起始索引位置cpot[col]

这里,还是以矩阵A举例。

col

1

2

3

4

5

6

num[col]

2

1

1

0

1

1

cpot[col]

1

3

4

 

5

6

从表格我们可以发现:cpot[col]=cpot[col-1]+num[col]

算法思路:

①构建映射关系。即初始化num[col]cpot[col]

②将结点放到指定的位置。

代码实现:

// 稀疏矩阵的快速转置算法
public static Matrix fastTranspose(Matrix a) {Matrix b = new Matrix(a.cols, a.rows, a.vals);int num[] = new int[a.cols + 1];// 初始化 num[]for(int i = 1; i < a.vals; i++) {++num[a.data[i].j];}int cpot[] = new int[a.cols + 1];// 初始化 cpot[]cpot[1] = 1;for(int col = 2; col < num.length; col++) {cpot[col] = cpot[col-1] + num[col];}for(int index = 1; index <= a.vals; index++) {int col = a.data[index].j;int newIndex = cpot[col];b.data[newIndex].i = a.data[index].j;b.data[newIndex].j = a.data[index].i;b.data[newIndex].value = a.data[index].value;cpot[col]++;}return b;
}

代码讲解:

这里,初始化数组的时候,多开辟一个空间,是因为三元数组表的第一个元素)(索引为0的位置)存储的是矩阵的行数、列数以及非零元素的个数。


(欢迎评论指导!转载时,请注明出处,谢谢。)


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

相关文章

转置矩阵,逆矩阵和倒转置矩阵

单位矩阵&#xff1a; 转置矩阵(transpose matrix) 在线性代数中&#xff0c;矩阵A的转置是另一个矩阵AT&#xff08;也写做Atr, tA或A′&#xff09;由下列等价动作建立: 把A的横行写为AT的纵列把A的纵列写为AT的横行 形式上说&#xff0c;m n矩阵A的转置是n m矩阵 for 。…

矩阵的乘法和转置

矩阵的乘法 矩阵的转置 A的转置为 ​​​​​​​ 反对称矩阵主对角线上全为0&#xff1b;

矩阵与转置

1.转置矩阵 1.1转置矩阵简介 把矩阵A的行换成同序数的列得到的新矩阵&#xff0c;叫做A的转置矩阵(Transpose of a Matrix)&#xff0c;记作ATAT。 例如&#xff1a; 因此&#xff0c;转置矩阵的特点&#xff1a; &#xff08;1&#xff09;转置矩阵的行数是原矩阵的列数&…

矩阵转置

矩阵转置 1. n*n 对角线置换 #include <stdio.h> //编写函数&#xff1a;实现4*4矩阵的转置。 //要求&#xff1a;在main函数中定义二维数组、输入数据、输出原矩阵、调用函数、输出转置后的矩阵。 int ZhuanZhi(int arr[][4]){int temp;for(int i0;i<4;i){ for(int …

矩阵乘以它的转置

矩阵乘以它的转置 AA^T| |A| |A^T| |A||A| |A|^2即矩阵A乘以A的转置等于A的行列式的平方。 明显不等于啦&#xff0c;1*2的矩阵转置矩阵为2*1&#xff0c;那么1*2的矩阵乘以2*1的转置矩阵得到一个1*1的矩阵&#xff0c;而2*1的转置矩阵乘以1*2的矩阵得到一个2*2的矩阵 这个…

矩阵转置与矩阵相乘

1.转置矩阵 1.1转置矩阵简介 把矩阵A的行换成同序数的列得到的新矩阵&#xff0c;叫做A的转置矩阵(Transpose of a Matrix)&#xff0c;记作ATAT。 例如&#xff1a; 因此&#xff0c;转置矩阵的特点&#xff1a; &#xff08;1&#xff09;转置矩阵的行数是原矩阵的列数&…

gyp linux,使用gyp

GYP(Generate You Project)&#xff0c;生成IDE项目的工具&#xff0c;使用Python脚本写成&#xff0c;配置文件为JSON格式。 使用gyp需要两个环境&#xff0c;python和gyp。gyp可以直接在这里下载 git clone https://chromium.googlesource.com/external/gyp 一般下载到build/…

gyp ERR!报错解决

项目安装依赖包的时候&#xff0c;多次出现gyp ERR&#xff01;或者node-pre-gyp ERR!这种错&#xff0c;记录一下最近遇到的报错&#xff1a; 用过两次这种解决办法&#xff0c;都能把依赖下好&#xff0c;项目跑起来 npm instal --unsafe-perm 或者 yarn --unsafe-perm 运…

解决gyp err 错误

npm install 安装失败 有一堆报错&#xff0c;大概意思就是node-gyp没有安装成功&#xff0c;以及需要一些python的环境 解决步骤 1、安装python环境 2、以管理员身份执行 npm install --g --production windows-build-tools 3、之后在安装完成后会在C:WindowsSystem32里找到一…

gyp ERR! find Python 解决方案

命令行报错 npm install npm WARN deprecated fsevents2.1.3: "Please update to latest v2.3 or v2.2" npm WARN deprecated fsevents1.2.13: fsevents 1 will break on node v14 and could be using insecure binaries. Upgrade to fsevents 2.> heapdump0.3.…

node-gyp 报错

error C:\xxx\node_modules\fibers: Command failed. 设置后还是会报错需要下载Visual Studio 访问地址GitHub - nodejs/node-gyp: Node.js native addon build tool 安装完之后设置使用路径就好了 npm config set msvs_version "C:\Program Files (x86)\Microsoft Visual…

【解决】gyp ERR! node -v v12.7.0 gyp ERR! node-gyp -v v3.8.0 gyp ERR! not ok

使用npm install报错如下 原因 这是 node-sass、sass-loader 安装的版本和电脑安装的 node.js 版本不兼容导致的错误 解决办法 我的node.js版本是&#xff1a;v12.7.0 在项目目的package.json文件把 node-sass 和 sass-loader 的修改成如下版本&#xff0c;npm i…

npm ERR! gyp verb等一系列错

npm ERR! code 1 npm ERR! path F:\新桌面\大三下\生产实习\mock-devices-master\mock-devices-master\node_modules\node-sass npm ERR! command failed npm ERR! command C:\WINDOWS\system32\cmd.exe /d /s /c node scripts/build.js npm ERR! Building: E:\Environment\Nod…

gyp ERR find Python 解决方案

命令行报错如下 E:\vue-admin\node_modules\fibers>if not defined npm_config_node_gyp (node "D:\nodejs\node_modules\npm\node_modules\npm-lifecycle\node-gyp-bin\\..\..\node_modules\node-gyp\bin\node-gyp.js" rebuild --releas e ) else (node "…

数据库-查询数据

查询表中所有字段数据&#xff1a;select * from 表名&#xff1b; 查询表中部分字段数据&#xff1a;select 字段1&#xff0c;字段2 from 表名&#xff1b; 3.运用关系运算符查询&#xff1a;select * from 表名 where 字段名 运算符 数值&#xff08;在单个字段的范围&am…

数据库查询语句

数据库查询语句无疑是所有语句中&#xff0c;最重要的语句&#xff0c;经常配合where一起使用 1. 最基本的查询 公式1&#xff1a;select * from 表名 -- 查看aaa表中的所有数据 SELECT * FROM aaa 你说&#xff0c;我不想查看表中所有的数据&#xff0c;我就想查看表中id字…

数据库查询和数据操纵

根据实验2在学生作业管理数据库Mydb中创建的学生表、课程表和学生作业表&#xff0c;进行以下操作。 使用查询语句完成以下任务&#xff08;每一个查询都要给出SQL语句&#xff0c;并且列出查询结果&#xff09;。 &#xff08;1&#xff09;查询与“张志国”同一班级的学生信息…

数据库中的数据查询

数据库中的数据查询 数据库表是存储数据库中所有数据的对象。在表中&#xff0c;数据按行和列格式逻辑组织&#xff0c;类似于电子表格。 在表中&#xff0c;每行代表一个唯一记录&#xff0c;每列代表记录中的一个字段。例如&#xff0c; SYS_User表包含用户数据&#xff0c;…

数据库---数据查询

实验目的 熟练掌握使用SQL查询语言。完成各类查询操作&#xff08;单表查询&#xff0c;连接查询&#xff0c;嵌套查询&#xff0c;集合查询&#xff09;。 实验内容 现有一个单位内部的小型图书借阅系统&#xff0c;假设每本图书的数量无限制&#xff0c;并且可以借给任何单…

MySQL数据库数据查询

1.投影查询 1.1 查询student表中所有学生的学号、姓名和专业。 1.2 查询student表中所有列。 1.3 查询student表中所有学生的学生的sno、sname、speciality&#xff0c;并将结果中各列的标题分别修改为学号, 姓名, 专业。 1.4 设student1表的表结构和样本数据与student表相同…