-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSparseMatrix.txt
More file actions
177 lines (144 loc) · 3.42 KB
/
SparseMatrix.txt
File metadata and controls
177 lines (144 loc) · 3.42 KB
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#define _CRT_SECURE_NO_DEPRECATE
#pragma once
#include<iostream>
#include<vector>
using namespace std;
//稀疏矩阵
/* M*N 的矩阵,矩阵中有效值的个数远小于无效值得个数,而且这些数据的分布没有规律*/
template<class T>
struct Triple //使用三元组存储每一个有效数据,三元组按原矩阵中的位置,以行优先级先后顺序存储;
{
size_t _row; //行
size_t _col; //列
T _value; //有效值
Triple(size_t row = 0, size_t col = 0, T value = 0)
:_row(row)
, _col(col)
{
_value = value;
}
};
template<class T>
class SparseMatrix
{
public:
SparseMatrix()
{
}
SparseMatrix(T * a, size_t N, size_t M, const T & invalue = T())
:_N(N)
, _M(M)
,_invalue(invalue)
{
for (size_t i = 0; i < _N; i++)
{
for (size_t j = 0; j < _M; j++)
{
if (a[i*_M + j] != invalue)
{
Triple<T> t(i, j, a[i*_M + j]);
_matrix.push_back(t);
}
}
}
}
void DisPlay()
{
size_t index = 0;
for (size_t i = 0; i < _N; i++)
{
for (size_t j = 0; j < _M; j++)
{
if (index < _matrix.size() && i == _matrix[index]._row && j == _matrix[index]._col)
{
cout << _matrix[index]._value << " ";
++index;
}
else
{
cout << _invalue << " ";
}
}
cout << endl;
}
cout << endl;
}
//矩阵的转置,行列对换
SparseMatrix<T> Transport()
{
SparseMatrix<T> tp; //转置后,为_M*_N 矩阵
tp._N = _M;
tp._M = _N;
//tp._matrix.resize(_matrix.size());
tp._invalue = _invalue;
for (size_t i = 0; i < _N; i++) //依次遍历三元组:在原矩阵中以列遍历,也就是转置后的以行优先级存储的三元组;
{
size_t index = 0;
while (index < _matrix.size())
{
if (_matrix[index]._col == i) //遍历每一列,找到三元组,以原矩阵的列优先级压栈;
{
Triple<T> t(_matrix[index]);
swap(t._col,t._row);
tp._matrix.push_back(t);
}
++index;
}
}
return tp;
}
//稀疏矩阵的快速转置
SparseMatrix<T> FastTransport()
{
SparseMatrix<T> tp;
tp._M = _N;
tp._N = _M;
tp._invalue = _invalue;
tp._matrix.resize(_matrix.size());
int *count = new int [_M]; //转置后每一行有几个有效数据;
memset(count, 0, sizeof(int)* _M);
int *start = new int [_M]; //转置周每一行第一个元素的所在三元组的位置;
size_t index = 0;
while (index < _matrix.size())
{
count[_matrix[index]._col]++; //遍历 一次三元组,对应列 出现数据直接++最后就得出每列数据的个数;
index++;
}
start[0] = 0;
for (size_t i = 1; i < _M; i++)
{
start[i] = start[i - 1] + count[i - 1]; //start与count 之间的对应关系;
}
index = 0;
while (index < _matrix.size())
{
int row = _matrix[index]._col; //转置后的行
Triple<T> t(_matrix[index]);
swap(t._col,t._row);
tp._matrix[start[row]] = t;
start[row]++;
index++;
}
return tp;
}
protected:
size_t _N; //N*M矩阵
size_t _M; //列
T _invalue; //无效值
vector<Triple<T>> _matrix; //链表,每有一个数据插入(因为不知道稀疏矩阵中的有效值个数,不好直接开空间)
};
void SpmTest()
{
int a[6][5] = {
{ 0, 0, 3, 0, 5 },
{ 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0 },
{ 2, 0, 4, 0, 6 },
{ 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0 },
};
SparseMatrix<int> sm((int*)a, 6, 5, 0);
sm.DisPlay();
sm.Transport().DisPlay();
sm.FastTransport().DisPlay();
}