稀疏矩阵的普通转置与快速转置算法
2016-05-09 17:49
537 查看
稀疏矩阵的普通转置与快速转置算法
一般来说,对于系数矩阵,我们使用三元组来存储。即就是将矩阵的所有非零元素的三元组存放在一个顺序表中,如图所示:
注意一个转置的前提:该顺序表是排好序的,即行优先,列其次。
一、普通转置
这种算法比较简单,也很容易想到:算法思想:
对M.data从头至尾扫描:«第一次扫描时,将M.data中列号为1的三元组赋值到T.data中
«第二次扫描时,将M.data中列号为2的三元组赋值到T.data中
«依此类推,直至将M.data所有三元组赋值到T.data中
代码
//转置运算算法 void transpose2(TSMatrix M, TSMatrix T) {//采用三元组表存储表示,求稀疏矩阵M的转置矩阵T T.rows=M.rows; T.size=M.size;; q=1; // q为当前三元组在T.data[ ]存储位置(下标) for (col=1; col<=M.cols; ++col) for (p=1; p<=M.size; ++p) if (M.data.get(p).j= =col){ T.data.get(q).i =M.data.get(p).j; T.data.get(q).j=M.data.get(p).i; T.data.get(q).value=M.data.get(p).value; ++q; } }
二、快速转置
这种算法往往理解起来较为困难。算法思想:
«按M中三元组次序转置,转置结果放入T中恰当位置。«关键
v预先确定M中每一列第一个非零元在T中位置
v为确定这些位置,转置前应先求得M的每一列中非零元个数
«实现:设两个数组num[ ]
、cpos[ ]
vnum[col]:存储M中第col列非零元个数
vcpos[col]:存储M中第col列第一个非零元三元组在T.data中的位置
«cpos[col]的计算方法:
vcpos[1]=1
vcpos[col]=cpos[col-1]+num[col-1]
(2<=col <=M.nu)
代码:
//稀疏矩阵快速转置算法(C语言描述) void Transpose (TSMatrix M, TSMatrix &T) { //采用三元组顺序表存储表示,求稀疏矩阵M的转置矩阵T T.m=M.n; T.n=M.m; T.tu=M.tu; //将M的行数赋值给T的列数,将M的列数赋值给T的行数,非零元素总数也赋值过去 for (col=1; col<=M.nu; ++col) num[col]=0; //初始化假设原三元组每一列都是0 for (t=1; t<=M.tu; ++t) ++num[M.data[t].j]; //枚举每一个非0元素, M.data[t].j 为其相应的列 cpot[1]=1; //求第 col列中第一个非零元在T.data中的序号 for(col=2; col<=M.t; ++col) //<span style="color:black;"><span style="color:black;"><span style="color:black;">存储</span><span style="color:black;">M</span><span style="color:black;">中第</span><span style="color:black;">col</span><span style="color:black;">列第一个非零元三元组在</span><span style="color:black;">T.data</span><span style="color:black;">中的位置</span></span></span> cpot[col]=cpot[col-1]+num[col-1]; for(p=1; p<M.tu; ++p) { //枚举所有的三元组 col=M.data[p].j; //将第i个三元组的列数赋值给col q=cpot[col]; /*取出cpot数组中cpot[col]的值,注意,这里很重要:因为在顺序表中,所有的行元素的大小已经是依次排好的, 所以我们遍历到的这个三元组时,当其与其后面的拥有相同列元素的三元组进行比较的时候,它一定是最小的, 所以应该放在前面时,所以我们取完这个值之后,将cpot[col]的值+1,即可在下面的遍历中搜索到与之邻近的 值,正好下标已经+1,直接添加上去即可*/ T.data[q].i=M.data[p].j; T.data[q].j=M.data[p].i; T.data[q].value=M.data[p].value;//赋值操作 ++cpot[col]; //下标记录+1 } }
相关文章推荐
- 奋斗吧,程序员——第三十二章 十年磨一剑,霜刃未曾试
- 基本数据类型
- ZOJ 3875-Lunch Time【模拟】
- JDBC学习笔记
- Job和Task运行时信息的维护
- javabean学习
- R-tree 一种空间搜索的动态索引结构
- 修改mysql错误提示语言的方法
- linux基础(13)--进程管理--RHEL6.5
- Android textView 获取行数
- Kettle Carte简介
- Struts1 学习
- Demo2 实现侧滑菜单:DrawerLayout布局初涉
- ijkplayer在windows下编译并导入Android Studio
- android 实现listview的adapter多种布局方式
- 你是不是想得太简单了
- 协议如何保证可靠传输
- MySQL 查看最大连接数, 当期连接数.
- vim 配置文件——部分配置
- 线程 进程区别