稀疏矩阵

有的时候我们需要将二维数组进行压缩, 实现资源的充分利用
比如: a[4][4]={
1, 2, 0, 0
4, 0, 0, 3
0, 5
};
数组为0的空间都是没有利用的, 所以就需要将为的地方进行压缩
功能实现查找, 转置
重要的代码都在下面, 注释也写了

声明如下:

#include <stdio.h>
#include <stdlib.h>
#include "稀疏矩阵-define-结构体.h"

// 结构体 1 , 储存数组的位置以及数字
struct Note
{
    ElemType num;

    // 两个用来储存行号和列号
    int i_Note;
    int j_Note;
};

// 存储标号
struct NUM
{
    // i_times用来储存二维数组每行所出现的次数
    // i_num用来储存每行的第一个数在稀疏矩阵里的位置
    int *i_times;
    int *i_num;
};

struct P_Note
{
    // 析构
    ~P_Note()
    {
        delete[]P_NUM->i_num;
        delete[]P_NUM->i_times;
        delete P_NUM;
        delete[]a;
    }

    struct Note * a;
    struct NUM * P_NUM;

    // 储存数组的边界大小
    int i_P_Note_Max;
    int j_P_Note_Max;
    // 储存非零的元素个数
    int num;
};

// 构造
void Creat(P_Note &note, int i_p, int j_p);
// 创造稀疏矩阵, 对其进行初始化
void Creat_P_Note(P_Note &, ElemType p[][N], int i_p, int j_p);
// 进行转置
void Transpose_P_Note(P_Note &, P_Note &);
// 查找
ElemType Find(P_Note &, int, int);
// 计算标号
void Count(P_Note &);
// 输出
void Print(P_Note &, int, int);

函数定义

#include "稀疏矩阵-声明-结构体.h"

// 创造稀疏矩阵, 对其进行初始化
void Creat_P_Note(P_Note &note, ElemType p[][N], int i_p, int j_p)
{
    note.num = 0;
    // 计算元素除0的个数
    for (int i = 0; i < i_p; i++)
        for (int j = 0; j < j_p; j++)
            if (p[i][j])
                note.num++;

    Creat(note, i_p, j_p);

    int t = 0;
    // 将非0的元素储存起来
    for(int i = 0; i < i_p; i++)
        for (int j = 0; j < j_p; j++)
            if (p[i][j])
            {
                note.a[t].i_Note = i;
                note.a[t].j_Note = j;
                note.a[t].num = p[i][j];
                t++;
            }

    Count(note);
}

// 构造
void Creat(P_Note &note, int i_p, int j_p)
{
    // 将数组全部进行初始化
    note.P_NUM = new NUM;
    note.i_P_Note_Max = i_p;
    note.j_P_Note_Max = j_p;
    note.a = new Note[note.num];
    note.P_NUM->i_num = new int[i_p]();
    note.P_NUM->i_times = new int[j_p]();
}

// 计算标号
void Count(P_Note &note)
{
    int t = note.i_P_Note_Max;
    int i;
    for (i = 0; i < t; i++)
        note.P_NUM->i_num[i] = 0;

    int t1 = note.num;
    for (i = 0; i < t1; i++)
        note.P_NUM->i_num[note.a[i].i_Note]++;

    note.P_NUM->i_times[0] = 0;
    for (i = 1; i < t; i++)
        note.P_NUM->i_times[i] = note.P_NUM->i_times[i - 1] + note.P_NUM->i_num[i - 1];
}

// 进行转置
void Transpose_P_Note(P_Note &note, P_Note &Temp)
{
    // 将两个数组变革进行创建
    Temp.P_NUM = new NUM;
    Temp.i_P_Note_Max = note.j_P_Note_Max;
    Temp.j_P_Note_Max = note.i_P_Note_Max;
    Temp.a = new Note[note.num];
    Temp.P_NUM->i_num = new int[note.j_P_Note_Max]();
    Temp.P_NUM->i_times = new int[note.j_P_Note_Max]();

    // 分别进行初始化
    int t = note.j_P_Note_Max;
    int i, j;
    for (j = 0; j < t; j++)
        Temp.P_NUM->i_num[j] = 0;

    int num = note.num;
    for (j = 0; j < num; j++)
        Temp.P_NUM->i_num[note.a[j].j_Note]++;

    Temp.P_NUM->i_times[0] = 0;
    for (j = 1; j < t; j++)
        Temp.P_NUM->i_times[j] = Temp.P_NUM->i_times[j - 1] + Temp.P_NUM->i_num[j - 1];

    // 实现转置
    for (j = 0; j < num; j++)
    {
        t = Temp.P_NUM->i_times[note.a[j].j_Note]++;
        Temp.a[t].num = note.a[j].num;
        Temp.a[t].i_Note = note.a[j].j_Note;
        Temp.a[t].j_Note = note.a[j].i_Note;
    }
}


// 查找
// 使用一次循环, 实现输出
ElemType Find(P_Note &note, int i_note, int j_note)
{
    int i_max = note.i_P_Note_Max;
    int j_max = note.j_P_Note_Max;
    if (i_max < i_note || i_note < 0 || j_note < 0 || j_note > j_max)
        exit(0);

    // 采用2个表格进行查找
    int times = note.P_NUM->i_num[i_note];
    int t = note.P_NUM->i_times[i_note];
    int num;
    for (int i = 0; i < times; i++)
    {
        num = note.a[t].num;
        if (j_note == note.a[t++].j_Note)
            return num;
    }

    return 0;
}

// 二维数组的输出
void Print(P_Note &note, int i_p, int j_p)
{
    int t = 0;
    for (int i = 0; i < i_p; i++)
    {
        for (int j = 0; j < j_p; j++)
            if (i == note.a[t].i_Note && j == note.a[t].j_Note)
                printf("%d ", note.a[t++].num);
            else
                printf("0 ");

        printf("\n");
    }
}

define如下


#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define ElemType int
#define ElemType_Ch char
typedef int* PElemType;
const int N = 5;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值