矩阵压缩存储
三元组顺序表+行逻辑链接
数据结构
const int MAX_SIZE = 1000;
const int MAX_SIZE_OF_ROW = 100;
typedef struct {
int i, j;//行标、列标
int e;//元素
}Triple;
typedef struct {
Triple data[MAX_SIZE];//数据
int rpos[MAX_SIZE_OF_ROW];//各行第一个非零元的位置(行逻辑链接)
int mu, nu, tu;//行数、列数、非零元个数
}RLTMatrix;//三元组顺序表
RLTMatrix
矩阵转置
行列交换+重新排序
普通方法
按列查找、放入
快速转置
建立每列第一个非零元对应的三元组顺序表的行号的数组,逐个遍历三元组顺序表放入相应位置。(类似于计数排序)
矩阵乘法
公式:
M
(
i
,
j
)
=
∑
k
=
1
n
L
1
(
i
,
k
)
∗
L
2
(
k
,
j
)
M(i,j)=\sum_{k=1}^nL1(i,k)*L2(k,j)
M(i,j)=∑k=1nL1(i,k)∗L2(k,j)
(
1
≤
i
≤
m
1
,
1
≤
j
≤
n
2
)
(1\leq i \leq m_1 ,1\leq j \leq n_2)
(1≤i≤m1,1≤j≤n2)
源码
#include<iostream>
#include<stdlib.h>
using namespace std;
const int MAX_SIZE = 1000;
const int MAX_SIZE_OF_ROW = 100;
typedef struct {
int i, j;//行标、列标
int e;//元素
}Triple;
typedef struct {
Triple data[MAX_SIZE];//数据
int rpos[MAX_SIZE_OF_ROW];//各行第一个非零元的位置
int mu, nu, tu;//行数、列数、非零元个数
}RLTMatrix;//三元组顺序表
RLTMatrix CreatTMatrix(int** x, int m, int n)//构建三元组形式的矩阵
{
int i,*num;
num = new int[m];
for (i = 0; i < m; i++) num[i] = 0;
RLTMatrix T;
T.mu = m;
T.nu = n;
T.tu = 0;
for(i=0;i<m;i++)
for (int j = 0; j < n; j++)
if (x[i][j] != 0)
{
T.data[T.tu].i = i;
T.data[T.tu].j = j;
T.data[T.tu].e = x[i][j];
T.tu++;
num[i]++;
}
T.rpos[0] = 0;
for (i = 1; i < m; i++) T.rpos[i] = T.rpos[i - 1] + num[i - 1];//获得rpos
return T;
}
void PrintTMatrix(RLTMatrix T)//打印三元组
{
int i, j;
cout << "三元组" << endl;
for (i = 0; i < T.tu; i++)
cout << T.data[i].i << ' ' << T.data[i].j << ' ' << T.data[i].e << endl;
cout << "rpos" << endl;
for (i = 0; i < T.mu; i++)
cout << i << ' ' << T.rpos[i] << endl;
}
RLTMatrix FastTransposeRLTMatrix(RLTMatrix T)//三元组矩阵快速转置
{
int i, j, * num, * cpos;
RLTMatrix M;
M.mu = T.nu;
M.nu = T.mu;
M.tu = T.tu;
if (T.tu <= 0) return M;
num = new int[T.nu];
cpos = new int[T.nu];
for (i = 0; i < T.nu; i++) num[i] = 0;
for (i = 0; i < T.tu; i++) num[T.data[i].j]++;
for (M.rpos[0]=cpos[0] = 0, i = 1; i < T.nu; i++)
{
cpos[i] = cpos[i - 1] + num[i - 1];//每列第一个非零元的序号
M.rpos[i] = cpos[i];
}
for (i = 0; i < T.tu; i++)
{
int row = cpos[T.data[i].j]++;
M.data[row].i = T.data[i].j;
M.data[row].j = T.data[i].i;
M.data[row].e = T.data[i].e;
}
return M;
}
RLTMatrix MultRLTMatrix(RLTMatrix T1, RLTMatrix T2)//三元组矩阵乘法
{
int i, * temp;
RLTMatrix M;
M.mu = T1.mu; M.nu = T2.nu; M.tu = 0;
if (T1.tu * T2.tu == 0 || T1.nu != T2.mu) return M;
temp = new int[T1.nu];
for (i = 0; i < T1.mu; i++)//一行一行的确定相乘后的元素
{
int j, l, r;
M.rpos[i] = M.tu;//设置三元组矩阵的行逻辑
for (j = 0; j < T1.nu; j++) temp[j] = 0;//初始化各列元素累加器
l = T1.rpos[i];
if (i < T1.mu - 1) r = T1.rpos[i + 1];
else if (i == T1.mu - 1) r = T1.tu ;
for (; l < r; l++)
{
int k = T1.data[l].j;
int ll, rr;
ll = T2.rpos[k];
if (k < T2.mu - 1) rr = T2.rpos[k + 1];
else rr = T2.tu;
for (; ll < rr; ll++)
temp[T2.data[ll].j] += T1.data[l].e * T2.data[ll].e;
}
for(j=0;j<T1.nu;j++)//将结果压缩到三元组矩阵内
if (temp[j])
{
M.data[M.tu].i = i;
M.data[M.tu].j = j;
M.data[M.tu++].e = temp[j];
}
}
return M;
}
int main()
{
int i;
int** x, ** y, m, n;
RLTMatrix T1, T2, M;
cout << "请输入矩阵一:" << endl;
cin >> m >> n;
x = new int* [m];
for (i = 0; i < m; i++) x[i] = new int[n];
for (i = 0; i < m; i++)
for (int j = 0; j < n; j++)
cin >> x[i][j];
T1 = CreatTMatrix(x, m, n);
cout << "请输入矩阵二:" << endl;
cin >> m >> n;
y = new int* [m];
for (i = 0; i < m; i++) y[i] = new int[n];
for (i = 0; i < m; i++)
for (int j = 0; j < n; j++)
cin >> y[i][j];
T2 = CreatTMatrix(y, m, n);
cout << "矩阵一、二:" << endl;
PrintTMatrix(T1);
PrintTMatrix(T2);
cout << "转置后矩阵一" << endl;
M = FastTransposeRLTMatrix(T1);
PrintTMatrix(M);
M = MultRLTMatrix(T1, T2);
cout << "乘积矩阵为:" << endl;
PrintTMatrix(M);
return 0;
}
十字链表
数据结构
typedef struct Node {
int i, j;
int e;
struct Node* right, * down;
}Node,*Link;//十字链表的一个结点
typedef struct {
Link* rHead,* cHead;
int mu, nu, tu;
}CrossList;//十字链表
void Cr
矩阵加法
源码
#include<iostream>
#include<stdlib.h>
using namespace std;
typedef struct Node {
int i, j;
int e;
struct Node* right, * down;
}Node,*Link;//十字链表的一个结点
typedef struct {
Link* rHead,* cHead;
int mu, nu, tu;
}CrossList;//十字链表
void CrossListInsertNode(CrossList& L, Link& node)//Insert a new node into the CrossList
{
int i, j;
i = node->i; j = node->j;
//insert row
if (L.rHead[i] == NULL || L.rHead[i]->j > j)
{
node->right = L.rHead[i];
L.rHead[i] = node;
}
else
{
Link p;
for (p = L.rHead[i]; p->right && p->right->j <= j; p = p->right);
if (p->j == j)//该位置已有结点,进行加法操作
{
p->e += node->e;
free(node);
return;
}
else
{
node->right = p->right;
p->right = node;
}
}
//insert column
if (L.cHead[j] == NULL || L.cHead[j]->i < i)
{
node->down = L.cHead[j];
L.cHead[j] = node;
}
else
{
Link p;
for (p = L.cHead[j]; p->down && p->down->i < i; p = p->down);
node->down = p->down;
p->down = node;
}
L.tu++;
}
CrossList CreatCrossList(int** x, int m, int n)
{
int i, j;
CrossList L;
L.mu = m;
L.nu = n;
L.tu = 0;
L.rHead = (Link*)malloc(m * sizeof(Link));
L.cHead = (Link*)malloc(n * sizeof(Link));
for (i = 0; i < m; i++) L.rHead[i] = NULL;
for (i = 0; i < n; i++) L.cHead[i] = NULL;
for(i=0;i<m;i++)
for(int j=0;j<n;j++)
if (x[i][j])
{
Link newNode = (Link)malloc(sizeof(Node));
newNode->i = i;
newNode->j = j;
newNode->e = x[i][j];
CrossListInsertNode(L,newNode);
}
return L;
}
CrossList AddCrossListMatrix(CrossList l1, CrossList l2)
{
int i, j;
CrossList L;
L.cHead = NULL; L.rHead = NULL;
L.mu = 0; L.nu = 0; L.tu = 0;
if (l1.mu != l2.mu || l1.nu != l2.nu) return L;//These two matrices can`t be added
L.mu = l1.mu; L.nu = l1.nu;
L.rHead = (Link*)malloc(L.mu*sizeof(Link));
L.cHead = (Link*)malloc(L.nu * sizeof(Link));
for (i = 0; i < L.mu; i++) L.rHead[i] = NULL;
for (i = 0; i < L.nu; i++) L.cHead[i] = NULL;
if (l1.tu == 0 && l2.tu == 0) return L;//Both matrixes are null
for (i = 0; i < L.mu;i++)
{
Link p1, p2;
p1 = l1.rHead[i];
p2 = l2.rHead[i];
while (p1 || p2)
{
Link node1, node2;
node1 = (Link)malloc(sizeof(Node));
node2 = (Link)malloc(sizeof(Node));
node1->i = i; node2->i = i;
if (p2 == NULL)
{
node1->j = p1->j;
node1->e = p1->e;
CrossListInsertNode(L, node1);
p1 = p1->right;
}
else if (p1 == NULL)
{
node1->j = p2->j;
node1->e = p2->e;
CrossListInsertNode(L, node1);
p2 = p2->right;
}
else
{
node1->j = p1->j;
node2->j = p2->j;
if (p1->j == p2->j)
{
node1->e = p1->e + p2->e;
CrossListInsertNode(L, node1);
}
else
{
node1->e = p1->e;
node2->e = p2->e;
CrossListInsertNode(L, node1);
CrossListInsertNode(L, node2);
}
p1 = p1->right;
p2 = p2->right;
}
}
}
return L;
}
void PrintMatrix(CrossList L)
{
int i, * x;
x = new int[L.nu];
for (i = 0; i < L.mu; i++)
{
int j;
Link p;
for (j = 0; j < L.nu; j++) x[j] = 0;
for (p = L.rHead[i]; p; p = p->right) x[p->j] = p->e;
for (j = 0; j < L.nu - 1; j++) cout << x[j] << ' ';
cout << x[L.nu - 1] << endl;
}
}
int main()
{
CrossList l1, l2;
int** x;
int i, m, n;
cout << "请输入矩阵一:" << endl;
cin >> m >> n;
x = new int* [m];
for (i = 0; i < m; i++) x[i] = new int[n];
for (i = 0; i < m; i++)
for (int j = 0; j < n; j++)
cin >> x[i][j];
l1 = CreatCrossList(x, m, n);
cout << "请输入矩阵二:" << endl;
cin >> m >> n;
x = new int* [m];
for (i = 0; i < m; i++) x[i] = new int[n];
for (i = 0; i < m; i++)
for (int j = 0; j < n; j++)
cin >> x[i][j];
l2 = CreatCrossList(x, m, n);
CrossList l3 = AddCrossListMatrix(l1, l2);
cout << "两矩阵和为" << endl;
PrintMatrix(l3);
return 0;
}