数据结构教程 | 矩阵的压缩存储

Data Structure:Matrix Compression Storage


1 Introduction

In data structures, a compressed storage structure for some specific matrices is provided.

The special matrix we mentioned can be generally divided into the following two types:

  • A matrix containing a large number of identical data elements, such as a symmetric matrix;
  • Matrix containing a large number of 0, such as sparse matrix, upper or lower triangular matrix;

For the two types of matrices above, the compressed storage idea of the data structure is: only one of the same data elements (including element 0) in the matrix is stored.

2 Storage of symmetric matrix and upper/lower triangular matrix

With the idea of data structure compression storage, we can use one dimensional array to store symmetric matrix. Since the data on both sides of the diagonal in the matrix are equal, we only need to store one side of the diagonal (including the diagonal) in the array.

For example, to store the elements in the lower triangle of symmetric matrix, we need to substitute the row number i and column number j of each element into the following formula (i,j≥1):
在这里插入图片描述
If we need to store the elements in the upper triangle, the formula should be:
在这里插入图片描述
An example:
在这里插入图片描述
The matrix above will be stored as:
在这里插入图片描述

3 Storage of sparse matrix

The method of compressing and storing the sparse matrix is to store the non-zero elements in the matrix only. Unlike the previous storage method, the storage of the non-zero elements of the sparse matrix needs to store the row and column labels in the matrix in which the element is located. Also we need to store the size of matrix.

Here are three ways to store a sparse matrix:

  • Triple sequence table
  • Logical-linked sequence table
  • Cross link list

3.1 Triple sequence table

First we will construct the basic structure:

// Structure of triad
typedef struct{
	int i,j;		// Index number
	int data;		// value
}triple;

// Structure of matrix
typedef struct{
	triple data[number];	// Store all the non-zero triple
	int n,m,num;			// n*m: size of the matrix, num: number of non-zero elements
}TSMatrix;

Then try the output:

void display(TSMatrix M){
    for(int i=1;i<=M.n;i++){
        for(int j=1;j<=M.m;j++){
            int value =0;
            for(int k=0;k<M.num;k++){
                if(i == M.data[k].i && j == M.data[k].j){
                    printf("%d ",M.data[k].data);
                    value =1;
                    break;
                }
            }
            if(value == 0)
                printf("0 ");
        }
        printf("\n");
    }
}

int main() {
    TSMatrix M;
    // Initialize the matrix
    M.m=3;
    M.n=3;
    M.num=3;
    
    // All the non-zero elements here
    M.data[0].i=1;
    M.data[0].j=1;
    M.data[0].data=1;
    M.data[1].i=2;
    M.data[1].j=3;
    M.data[1].data=5;
    M.data[2].i=3;
    M.data[2].j=1;
    M.data[2].data=3;
    display(M);
    return 0;
}

Output:
在这里插入图片描述

3.2 Logical-linked sequence table

This storage method is similar with triple sequence table but it improve the efficiency of extracting data.
This method also record the first non-zero element in each row.
在这里插入图片描述
Storage:
在这里插入图片描述
在这里插入图片描述
Code implementation:

/* Sparse matrix storage(Logical-linked sequence table) */
#include <stdio.h>
#define MAXSIZE 12500
#define MAXRC 100
#define ElemType int
typedef struct
{
    int i,j;
    ElemType e;
}Triple;
typedef struct
{
    Triple  data[MAXSIZE+1];
    int rpos[MAXRC+1];	// First position of non-zero elements in every row
    int mu,nu,tu;		// row,column,number of elements
}RLSMatrix;

void display(RLSMatrix M){
    for(int i=1;i<=M.mu;i++){
        for(int j=1;j<=M.nu;j++){
            int value=0;
            if(i+1 <=M.mu){
                for(int k=M.rpos[i];k<M.rpos[i+1];k++){
                    if(i == M.data[k].i && j == M.data[k].j){
                        printf("%d ",M.data[k].e);
                        value=1;
                        break;
                    }
                }
                if(value==0){
                        printf("0 ");
                    }
            }else{
                for(int k=M.rpos[i];k<=M.tu;k++){
                    if(i == M.data[k].i && j == M.data[k].j){
                        printf("%d ",M.data[k].e);
                        value=1;
                        break;
                    }
                }
                if(value==0){
                    printf("0 ");
                }
            }
        }
        printf("\n");
    }
}
int main(int argc, char* argv[])
{
    RLSMatrix M;
    M.tu = 4;
    M.mu = 3;
    M.nu = 4;
    M.rpos[1] = 1;
    M.rpos[2] = 3;
    M.rpos[3] = 4;
    M.data[1].e = 3;
    M.data[1].i = 1;
    M.data[1].j = 2;
    M.data[2].e = 5;
    M.data[2].i = 1;
    M.data[2].j = 4;
    M.data[3].e = 1;
    M.data[3].i = 2;
    M.data[3].j = 3;
    M.data[4].e = 2;
    M.data[4].i = 3;
    M.data[4].j = 1;
    display(M);
    return 0;
}

Output:
在这里插入图片描述

3.3 Cross link list

If we want to add or delete non-zero elements, the two storage methods above will not be suitable, so we introduce a new idea: Cross link list. It combines link list and array:
在这里插入图片描述
Code implementation:

/* Sparse matrix storage(Cross link list) */
#include<stdio.h>
#include<stdlib.h>

typedef struct OLNode
{
    int i,j,e;                      // i:row;j:column;e:value
    struct OLNode *right,*down;     // right pointer and down pointer
}OLNode,*OLink;

typedef struct
{
    OLink *rhead,*chead;            // Head pointer for row and column
    int mu,nu,tu;                   // Size of matrix and the number of non-zero elements
}CrossList;

CrossList CreateMatrix_OL(CrossList M)
{
    int m,n,t;
    int i,j,e;
    OLNode *p,*q;
    printf("Row column and non-zero elements:");
    scanf("%d %d %d",&m,&n,&t);
    M.mu=m;
    M.nu=n;
    M.tu=t;
    if(!(M.rhead=(OLink*)malloc((m+1)*sizeof(OLink)))||!(M.chead=(OLink*)malloc((n+1)*sizeof(OLink))))
    {
        printf("Failed to initalize the matrix");
        exit(0);
    }
    for(i=1;i<=m;i++)
    {
        M.rhead[i]=NULL;
    }
    for(j=1;j<=n;j++)
    {
        M.chead[j]=NULL;
    }
    for(scanf("%d %d %d",&i,&j,&e);0!=i;scanf("%d %d %d",&i,&j,&e))    {
        if(!(p=(OLNode*)malloc(sizeof(OLNode))))
        {
            printf("Failed to initalize the triple");
            exit(0);
        }
        p->i=i;
        p->j=j;
        p->e=e;
        // Link to row
        if(NULL==M.rhead[i]||M.rhead[i]->j>j)
        {
            p->right=M.rhead[i];
            M.rhead[i]=p;
        }
        else
        {
            for(q=M.rhead[i];(q->right)&&q->right->j<j;q=q->right);
            p->right=q->right;
            q->right=p;
        }
        // link to column
        if(NULL==M.chead[j]||M.chead[j]->i>i)
        {
            p->down=M.chead[j];
            M.chead[j]=p;
        }
        else
        {
            for (q=M.chead[j];(q->down)&& q->down->i<i;q=q->down);
            p->down=q->down;
            q->down=p;
        }
    }
    return M;
}
void display(CrossList M){
    for (int i=1;i<=M.nu;i++)
    {
        if (NULL!=M.chead[i])
        {
           OLink p=M.chead[i];
            while (NULL!=p)
            {
                printf("Col:%d\tRolL%d\tVal:%d\n",p->i,p->j,p->e);
                p=p->down;
            }
        }
    }
}
int main()
{
    CrossList M,N;
    M=CreateMatrix_OL(M);
    printf("M:\n");
    display(M);
    return 0;
}

Output:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值