11、稀疏矩阵的压缩存储

1、稀疏矩阵的压缩存储定义和初始化

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<assert.h>
#include<memory.h>

#define ElemType int
#define MAXSIZE 100

typedef struct Triple{
    int row;//数据所在行 
    int col;//数据所在列 
    ElemType value;//数据 
}Triple;

typedef struct SMatrix{
    Triple data[MAXSIZE];
    int total_row;//总行数 m行 
    int total_col;//总列数  n行
    int not_zero_count;//非零元素个数 
}SMatrix;// Spare Mastrix

void CreateMatrix(SMatrix *M){
    FILE *fp = fopen("C:\\Users\\16326\\Desktop\\ds\\matrix.txt","r");
    if(fp == NULL){
        exit(1);
    }
    fscanf(fp, "%d %d", &M->total_col, &M->total_row);
    //printf("%d %d", M->mu, M->nu);
    int value;
    int k = 0;//记录data数组下标 ,也是非零元素个数 
    int i =0, j = 0;
    for(i = 0;i < M->total_col;i++){//遍历行 
        for(j = 0;j < M->total_row;j++){//遍历列 
            fscanf(fp,"%d",&value);
            if(value != 0){
                M->data[k].value = value;//记录数据 
                M->data[k].row = i;//记录行 
                M->data[k].col = j;//记录列
                k++; //非零元素个数 ++
            }
        }
    }
    M->not_zero_count = k;//记录非零元素个数 
    fclose(fp);//关闭流 
}
/*
matrix.txt
6 7
0 12 9 0 0 0 0
0 0 0 0 0 0 0
-3 0 0 0 0 14 0
0 0 24 0 0 0 0
0 18 0 0 0 0 0
15 0 0 -7 0 0 0
*/

2、稀疏矩阵转置和快速转置方法

//将 M 转置后储存到 T 中 
void transposeMatrix(SMatrix *M,SMatrix *T){
    T->total_row = M->total_col;
    T->total_col = M->total_row;
    T->not_zero_count = M->not_zero_count;
    
    
    int i = 0,k = 0,q = 0;
    //遍历列,从第一列开始转置
    for(i;i < M->total_col;i++){
        //遍历所有非零元素 
        for(k = 0;k < M->not_zero_count;k++){
            if(M->data[k].col == i){
                T->data[q].value = M->data[k].value;
                T->data[q].col = M->data[k].row;
                T->data[q].row = M->data[k].col;
                q++;
            }
        }
    } 
    
}

void FastTransposeMatrix(SMatrix* M,SMatrix* T){
    if(M->not_zero_count == 0)
        return;
    T->total_row = M->total_col;
    T->total_col = M->total_row;
    T->not_zero_count = M->not_zero_count;
     
    //用于记录每一列非零元素的个数 
    int* num = (int*)malloc(sizeof(int) * M->total_col);
    assert(num != NULL);
    //用于记录每一列的应该存储在数组的下标位置
    int* cpos = (int*)malloc(sizeof(int) * M->total_col);    
    assert(cpos != NULL);
    
    int col = 0;
    //初始化num 
    for(col = 0;col < M->total_col;col++)
        num[col] = 0;
    
    //遍历所有的非零元素,记录每一列非零元素的个数
    int i = 0;
    for(i = 0;i < M->not_zero_count;i++){
        col = M->data[i].col;
        num[col]++; 
    } 
    
    //初始化第一列的元素在对应起始下标位置为0 
    cpos[0] = 0;
    //其他列为上一列的起始位置加上一列非零元素的个数 
    for(col = 1;col < M->total_col;col++){
        cpos[col] = cpos[col - 1] + num[col - 1];
    }
    
    //进行转置
    int pos = 0;
    for(i = 0;i < M->not_zero_count;i++){
        //获取该元素所在列 
        col = M->data[i].col;
        //获取该元素应该存储在目标数组的下标 
        pos = cpos[col]; 
        
        T->data[pos].value = M->data[i].value;
        T->data[pos].col = M->data[i].row;
        T->data[pos].row = M->data[i].col;
        //该列的下一个元素存储在目标数据下标 
        cpos[col]++;
    } 
}

3、其他方法实现

void PrintMatrix(SMatrix *M){ 
    int i = 0;
    printf("row=%d, col=%d\n",M->total_row,M->total_col); 
    for(i = 0;i < M->not_zero_count;i++){
        //注意:行和列从0开始
        printf("(%d,%d,%d)\n",M->data[i].row,M->data[i].col,M->data[i].value);
    }
}

void CopyMatrix(SMatrix *M, SMatrix *T){
    T->total_row = M->total_row;
    T->total_col = M->total_col;
    T->not_zero_count = M->not_zero_count;
    
    int k = 0;
    for(k;k < M->not_zero_count;k++){
        T->data[k].row = M->data[k].row; 
        T->data[k].col = M->data[k].col; 
        T->data[k].value = M->data[k].value; 
    }
}

 

posted @ 2024-09-27 09:03  颜欢兮  阅读(5)  评论(0编辑  收藏  举报