博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【数据结构之旅】稀疏矩阵的快速转置
阅读量:7208 次
发布时间:2019-06-29

本文共 3093 字,大约阅读时间需要 10 分钟。

说明:

    稀疏矩阵的快速转置算法的核心在于,用一个数组num记录原来矩阵中的每列非零元个数,用另一个数组cpos来记录原矩阵每列第一个非零元在新矩阵中的位置,以此来达到快速转置的目的。

    用这样的方法,主要是希望,矩阵转置后,存储顺序依然是按照行来存储的。


1.实现及代码注释

    根据上面的核心提示,可以有如下的代码,下面的代码中的注释已经非常详细,因此这里就不把每一部分实现的功能独立开来了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#
include
<stdio.h>
#
include
<stdlib.h>
#define OVERFLOW -
1
#define OK 
1
#define ERROR 
0
#define TRUE 
2
#define FALSE -
2
 
typedef 
int 
ElemType;
typedef 
int 
Status;
 
typedef struct{ 
//非零元三元组类型结构体 
    
int 
i, j; 
//非零元的行和列 
    
ElemType e;    
//非零元的值 
} Triple;      
//非零元三元组类型结构体定义关键字
 
typedef struct{        
//矩阵类型结构体 
    
Triple *data;  
//data域,指向非零元三元组的结构体指针 
    
int 
mu, nu, tu;  
//矩阵的行数、列数和非零元个数 
} TSMatrix;            
//矩阵类型结构体定义关键字
 
 
/*
   
0   14  0   0   -5
   
0   -7  0   0   0
   
36  0   0   28  0
    
   
mu = 3; nu = 5; tu = 5
*/
 
Status CreateSMatrix(TSMatrix &M){    
//创建一个稀疏矩阵 
    
M.tu = 
5
;
     
    
M.data = (Triple*)malloc(sizeof(Triple) * (M.tu + 
1
)); 
//data域存储元素的大小比稀疏矩阵的非零元个数大1,是因为data[0]不使用 
    
if
(NULL == M.data)
        
return 
OVERFLOW;
    
M.data[
1
].i = 
1
;
    
M.data[
1
].j = 
2
;
    
M.data[
1
].e = 
14
;
     
    
M.data[
2
].i = 
1
;
    
M.data[
2
].j = 
5
;
    
M.data[
2
].e = -
5
;
     
    
M.data[
3
].i = 
2
;
    
M.data[
3
].j = 
2
;
    
M.data[
3
].e = -
7
;
     
    
M.data[
4
].i = 
3
;
    
M.data[
4
].j = 
1
;
    
M.data[
4
].e = 
36
;
     
    
M.data[
5
].i = 
3
;
    
M.data[
5
].j = 
4
;
    
M.data[
5
].e = 
28
;
     
    
M.mu = 
3
;
    
M.nu = 
5
;
     
    
return 
OK;
}
 
Status FastTransposeSMatrix(TSMatrix M, TSMatrix &T){ 
//采用顺序表存储表示,求稀疏矩阵M的转置矩阵T 
    
int 
j, p, q, t;
    
/*j记录遍历时的当前列,cops[j],则表示当前列第一个非零元的位置或者该列非零元位置的其它位置(cops[j]++),正式转置时用; 
    
p记录遍历时的非零元个数,正式转置时用; 
    
q记录cops[j],简化代码的表示,正式转置时用 ;
    
t用在转置准备时。 
    
*/
    
int 
*num;  
//保存每一列的非零元个数 
    
int 
*cpos; 
//保存转置后每列第一个非零元在T中所处的序号
                
//cops[j]++则是该列的下一个非零元,如果存在的话 
     
    
T.mu = M.nu; T.nu = M.mu; T.tu = M.tu;  
//初始化矩阵T 
     
    
T.data = (Triple*)malloc(sizeof(Triple)*(T.nu + 
1
));
     
    
num = (
int
*)malloc((M.nu + 
1
)*sizeof(
int
)); 
//num和cpos开辟空间比非零元个数大1,是因为不使用0号位置 
    
cpos = (
int
*)malloc((M.nu + 
1
)*sizeof(
int
));
     
    
if
(num == NULL || cpos == NULL)
        
return 
OVERFLOW;
     
    
if
(T.tu != 
0
){
        
for
(j = 
1
; j <= M.nu; j++) 
//初始化num向量 
            
num[j] = 
0
;
        
for
(t = 
1
;t <= M.tu; t++)   
//求M中每一列所含非零元的个数 
            
num[M.data[t].j]++;     
//这里要用到num[1]~num[5],所以上面num要全部初始化为0 
         
        
cpos[
1
] = 
1
;  
//这里是一定的 
        
for
(j = 
2
;j <= M.nu; j++)   
//求每列的第一个非零元在T.data中的序号  
            
cpos[j] = cpos[j-
1
] + num[j-
1
]; 
//画表分析得出该公式并不难 
         
        
for
(p = 
1
; p <= M.tu; p++){        
//上面是准备工作,下面开始正式转置 
            
j = M.data[p].j;  
//j的作用是记录当前遍历的列,以让cops使用 
            
q = cpos[j];      
//是为了简化代码,因为下面都要用到cpos[j] 
            
T.data[q].i = M.data[p].j;    
//交换行 
            
T.data[q].j = M.data[p].i;    
//交换列 
            
T.data[q].e = M.data[p].e;    
//赋值 ,无论如何交换,储存顺序是已经定下来的了 
                                         
            
cpos[j]++;  
//cops[j]++则是该列的下一个非零元,如果存在的话,不存在的话也没有影响 
        
}               
//因为在这个for循环中,如果列变了,即j变化了,cpos[j]也不是原来的值了 
    
    
free(num);
    
free(cpos);
    
return 
OK;
}
 
int 
main(
void
){
    
int 
i,j;
     
    
TSMatrix M;
    
TSMatrix T;
    
CreateSMatrix(M);  
    
FastTransposeSMatrix(M, T);
     
    
printf(
"\n"
);
    
return 
0
;
}

    可以用C free等编译器进行编译运行,但由于时间关系,上面的代码中并没有给出转置后的矩阵打印的代码,可以自己加上去,当然也可以通过调试的方法监视新矩阵T中的data域的数值变化。


2.测试

    测试就是按照上面的提示去做就可以了,时间关系,这里就先不做测试,改天有时间再补上吧。

转载地址:http://jumum.baihongyu.com/

你可能感兴趣的文章
CLR的执行模型(4):执行程序集的代码
查看>>
同一脚本sh 脚本名 报Syntax error: "(" unexpected而./脚本名不报错,求解!!
查看>>
ZJOI2008皇帝的烦恼
查看>>
新手windows安装nginx
查看>>
浏览器兼容问题踩坑收集
查看>>
Python 实用技巧
查看>>
object c中@property 的使用
查看>>
Sping 核心IOC容器
查看>>
poj 2524
查看>>
MapReduce
查看>>
论文阅读笔记五十六:(ExtremeNet)Bottom-up Object Detection by Grouping Extreme and Center Points(CVPR2019)...
查看>>
回收期计算
查看>>
response响应
查看>>
10 个十分难得的 javascript 开发经验
查看>>
Common Subsequence
查看>>
【CSS3】标签使用说明
查看>>
n皇后问题—回溯法 C++实现
查看>>
on delete cascade
查看>>
Connected Graph
查看>>
openfile iscisi 配置
查看>>