矩阵压缩存储

矩阵压缩存储

三元组顺序表+行逻辑链接

数据结构

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) (1im1,1jn2)

源码

#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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值