数据结构 - 稀疏矩阵的封装(三元组,行逻辑链接)

稀疏矩阵(三元组,行逻辑连接)

本次代码将关于基本三元组和行逻辑链接表示的三元组进行了封装,还附加了两个系数矩阵的乘法和加法,欢迎大家参考测试代码。

#pragma once
#include <iostream>
#include <queue>
#include <vector>
#define MAXSIZE 100
using namespace std;

typedef struct node {
    int val;
    int row;
    int col;
    node(int v, int r, int c) :val(v), row(r), col(c) {}
    node() {}
}LinkNode;

class Triad
{
public:
    Triad(int x, int y) :rn(x), cn(y) {}
    Triad() {}      //无参构造
    void input();   //输入矩阵
    void show();    //展示稀疏矩阵
    void GetRopt(); //获取行逻辑链接
    void GetCopt(); //获取列逻辑链接
    int  find(int r, int c); //查找矩阵中的某一个值
    Triad FastTranspose();   //转置返回一个三元组类
    Triad operator*(Triad &b);//乘法运算
    Triad operator+(Triad &b);//加法运算
private:
    LinkNode arr[MAXSIZE + 1];    //存储非零元素
    int rn; //行
    int cn; //列
    int tn; //非零元素个数
    int copt[MAXSIZE + 1];
    int ropt[MAXSIZE + 1];
};

void Triad::input()
{
    int x = 0,k = 1;
    for (int i = 1; i <= rn; i++)
    {
        for (int j = 1; j <= cn; j++)
        {
            cin >> x;
            if (x != 0)
            {
                LinkNode n(x, i, j);
                arr[k++] = n;
            }
        }
    }
    tn = k - 1;
}

void Triad::show()
{
    for (int i = 1; i <= this->tn; i++)
    {
        printf("arr[%d][%d] = %d\n", this->arr[i].row, this->arr[i].col, this->arr[i].val);
    }
}

int Triad::find(int i, int j)
{
    for (int i = 1; i <= tn; i++)
    {
        if (arr[i].row == i && arr[i].col == j)
            return arr[i].val;
    }
    return 0;
}
//获取行逻辑链接
void Triad::GetRopt()
{
    if (this->tn) {
        int nums[MAXSIZE];
        fill(nums, nums + MAXSIZE, 0);
        fill(ropt, ropt + MAXSIZE + 1, 0);
        for (int i = 1; i <= this->tn; i++)
            ++nums[this->arr[i].row];
        this->ropt[1] = 1;
        for (int i = 2; i <= this->tn; i++)
            this->ropt[i] = this->ropt[i - 1] + nums[i - 1];
    }
}
void Triad::GetCopt()
{
    if (this->tn) {
        int nums[MAXSIZE];
        fill(nums, nums + MAXSIZE, 0);
        fill(copt, copt + MAXSIZE + 1, 0);
        for (int i = 1; i <= this->tn; i++)
            ++nums[this->arr[i].col];
        this->copt[1] = 1;
        for (int i = 2; i <= this->tn; i++)
            this->copt[i] = this->copt[i - 1] + nums[i - 1];
    }
}
//进行转置
Triad Triad::FastTranspose()
{
    Triad newmaxtri;
    this->GetCopt(); //获取列链接
    for (int i = 1; i <= tn; i++)
    {
        int col = arr[i].col;
        int   q = copt[col];
        newmaxtri.arr[q].row = arr[i].col;
        newmaxtri.arr[q].col = arr[i].row;
        newmaxtri.arr[q].val = arr[i].val;
        ++copt[col];
    }
    newmaxtri.tn = this->tn;
    newmaxtri.cn = this->rn;
    newmaxtri.rn = this->cn;
    return newmaxtri;
}

Triad Triad::operator*(Triad &b)
{
    Triad ans;
    if (this->cn != b.rn)
    {
        cout << "矩阵 a 的列数不等于矩阵 b 的行数,不能计算矩阵乘法 ab" << endl;
        exit(1);
    }

    //矩阵ans初始化
    this->GetRopt();
    b.GetRopt();
    ans.rn = this->rn; //初始化行
    ans.cn = b.cn;     //初始化列
    ans.tn = 0;

    int ctemp[MAXSIZE + 1];
    //逐行求积
    if (this->tn * b.tn != 0)
    {
        for (int arow = 1; arow <= this->rn; ++arow)
        {
            //累加器清零
            fill(ctemp, ctemp + MAXSIZE + 1, 0);

            //计算c中第arow行的积并存入ctemp[]中
            ans.ropt[arow]= ans.tn + 1;
            int tp;//this中的某一行的最后一个非零元素在copt中的位置
            if (arow < this->rn) tp = this->ropt[arow + 1];
            else tp = this->tn + 1;

            //拿出this中当前行的每个非零元素
            for (int i = this->ropt[arow]; i < tp; ++i)
            {
                int brow = this->arr[i].col;
                int t;
                if (brow < b.rn)t = b.ropt[brow + 1];
                else t = b.tn + 1;
                for (int q = b.ropt[brow]; q < t; ++q)
                {
                    int ccol = b.arr[q].col;
                    ctemp[ccol] += this->arr[i].val * b.arr[q].val;
                }
            }
            for (int ccol = 1; ccol <= ans.cn; ++ccol)
            {
                if (ctemp[ccol])
                {
                    if (++ans.tn > MAXSIZE)
                    {
                        cout << "错误:元素个数大于最大设定值" << endl;
                        exit(-1);
                    }
                    LinkNode tmp;
                    tmp.row = arow;
                    tmp.col = ccol;
                    tmp.val = ctemp[ccol];
                    ans.arr[ans.tn] = tmp;
                 }
            }
        }
    }
    return ans;
}

Triad Triad::operator+(Triad &b)
{
    Triad ans;
    int ia, ib,ic,ar,br,cr,ac,bc,cc;
    ia = ib = ic =1;
    while (ia <= this->tn && ib <= b.tn)
    {
        ar = this->arr[ia].row;
        br = this->arr[ib].row;
        if (ar > br)
        {
            cr = br;
            while (cr == b.arr[ib].row)
            {
                ans.arr[ic].row = cr;
                ans.arr[ic].col = b.arr[ib].col;
                ans.arr[ic].val = b.arr[ib].val;
                ++ib; ++ic;
            }
        }
        else if (ar < br)
        {
            cr = ar;
            while (cr == this->arr[ia].row)
            {
                ans.arr[ic].row = cr;
                ans.arr[ic].col = this->arr[ia].col;
                ans.arr[ic].val = this->arr[ia].val;
                ++ic; ++ia;
            }
        }
        else if (ar == br)
        {
            cr = ar;
            ac = this->arr[ia].col;
            bc = b.arr[ib].col;
            if (ac > bc)
            {
                ans.arr[ic].row = cr;
                ans.arr[ic].col = bc;
                ans.arr[ic].val = b.arr[ib].val;
                ++ic; ++ib;
            }
            else if (ac < bc)
            {
                ans.arr[ic].row = cr;
                ans.arr[ic].col = ac;
                ans.arr[ic].val = this->arr[ia].val;
                ++ic; ++ia;
            }
            else if (ac == bc)
            {
                if (this->arr[ia].val + b.arr[ib].val != 0)
                {
                    ans.arr[ic].row = cr;
                    ans.arr[ic].col = ac;
                    ans.arr[ic].val = this->arr[ia].val + b.arr[ib].val;
                    ++ic;
                }
                ++ia;
                ++ib;
            }
        }
    }
    while (ia <= this->tn)
    {
        ans.arr[ic].row = this->arr[ia].row;
        ans.arr[ic].col = this->arr[ia].col;
        ans.arr[ic].val = this->arr[ia].val;
        ++ic; ++ia;
    }
    while (ib <= b.tn)
    {
        ans.arr[ic].row = b.arr[ib].row;
        ans.arr[ic].col = b.arr[ib].col;
        ans.arr[ic].val = b.arr[ib].val;
        ++ic; ++ib;
    }
    ans.tn = --ic;
    return ans;
}

如果大家有什么疑问的话可以加qq向我提出哦,欢迎各位大佬指出问题。
如果你觉得对你有所帮助的话就给我点个赞,点燃我下次写文章的动力吧 ^_^ !

原文地址:https://www.cnblogs.com/wlw-x/p/11744190.html

时间: 2024-10-10 12:33:33

数据结构 - 稀疏矩阵的封装(三元组,行逻辑链接)的相关文章

稀疏矩阵的三元组行逻辑链接的顺序表存储结构表示及实现

#define MAX_SIZE 100 #define MAX_RC 20 struct Triple { int i, j;//行下标,列下标 ElemType e;//非零元素值 }; struct RLSMatrix { Triple data[MAX_SIZE + 1];//非零元三元组表,data[0]未用 int rpos[MAX_RC + 1];//各行第1个非零元素的位置表 int mu, nu, tu;//矩阵的行数,列数,非零元个数 }; int comp(int c1,

(数据结构第五章)行逻辑链接的顺序表

/*******************行逻辑链接的顺序表*****************/ #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define MAXSIZE 12500 /// 假设非零元个数最大值为12500 #define MAXRC 12500 ///假设的每行的个数的最大值12500 #define ERROR -1 typedef stru

行逻辑链接的矩阵乘法

Description 对于一个稀疏矩阵,当需要频繁的随机存取任意一行的非零元时,则需要知道每一行的第一个非零元在三元组表中的位置.为此,可以将算法5.2中用来指示“行”信息的辅助数组cpot固定在稀疏矩阵的存储结构中.这种“带行链接信息”的三元组表即为行逻辑链接的顺序表.其类型描述如下: 针对存储于行逻辑链接顺序表的稀疏矩阵,其矩阵相乘的算法与经典算法有所不同.因此,对于两个稀疏矩阵相乘(Q=M×N)的过程可以大致描述如下: 请使用行逻辑链接的顺序表实现两个稀疏矩阵的乘法. Input 输入的

堆栈队列和数组-行逻辑链接稀疏矩阵

#include<iostream> #include <iomanip> #include"windows.h" using namespace std; struct Tripple { int x,y,value; }; struct RLSMatrix { int r,c,cnt; Tripple* tripples; int* rpos; }; RLSMatrix* createRLSMatrix(int r,int c,int maxCnt) { R

5-3-行逻辑链接的顺序表(稀疏矩阵)-数组和广义表-第5章-《数据结构》课本源码-严蔚敏吴伟民版

课本源码部分 第5章  数组和广义表 - 行逻辑链接的顺序表(稀疏矩阵) ——<数据结构>-严蔚敏.吴伟民版        源码使用说明  链接??? <数据结构-C语言版>(严蔚敏,吴伟民版)课本源码+习题集解析使用说明        课本源码合辑  链接??? <数据结构>课本源码合辑        习题集全解析  链接??? <数据结构题集>习题解析合辑        本源码引入的文件  链接? Status.h.Scanf.c        相关测试

javascript实现数据结构: 稀疏矩阵之三元组线性表表示

稀疏矩阵(Sparse Matrix):对于稀疏矩阵,目前还没有一个确切的定义.设矩阵A是一个n*m的矩阵中有s个非零元素,设  δ=s/(n*m),称δ为稀疏因子, 如果某一矩阵的稀疏因子δ满足δ≦0.05时称为稀疏矩阵, 稀疏矩阵的压缩存储 对于稀疏矩阵,采用压缩存储方法时,只存储非0元素.必须存储非0元素的行下标值.列下标值.元素值.因此,一个三元组(i, j, aij)唯一确定稀疏矩阵的一个非零元素. 上图的稀疏矩阵A的三元组线性表为: ( (1,2,12), (1,3,9), (3,1

cat /proc/cpuinfo 引发的思考--CPU 物理封装-物理核心-逻辑核心-超线程之间关系

CPU的物理封装,一个物理封装使用独立的一个CPU物理插槽,共享电源和风扇: CPU物理核心:在一个物理封装中封装了多个独立CPU核心,每一个CPU核心都有自己独立的完整硬件单元. CPU逻辑核心:一个CPU物理核心对外表现为多个独立的外部CPU接口,称这种每一个CPU接口为一个逻辑核心.其内部可能共享运行单元和缓存等. CPU逻辑核心是超线程技术下的产物,假设没有超线程技术,有多少颗物理CPU核心,OS就觉得有多少颗CPU.OS是根据CPU的外部接口来识别CPU数据,而不是根据CPU的实际内部

数据结构实验之栈:行编辑器

数据结构实验之栈:行编辑器 题目描述 一个简单的行编辑程序的功能是:接受用户从终端输入的程序或数据,并存入用户的数据区. 由于用户在终端上进行输入时,不能保证不出差错,因此,若在编辑程序中,“每接受一个字符即存入用户数据区”的做法显然不是最恰当的.较好的做 法是,设立一个输入缓冲区,用以接受用户输入的一行字符,然后逐行存入用户数据区.允许用户输入出差错,并在发现有误时可以及时更正.例如,当用户发现刚 刚键入的一个字符是错的时,可补进一个退格符"#",以表示前一个字符无效: 如果发现当前

SDUT OJ 1479 数据结构实验之栈:行编辑器

数据结构实验之栈:行编辑器 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 一个简单的行编辑程序的功能是:接受用户从终端输入的程序或数据,并存入用户的数据区. 由于用户在终端上进行输入时,不能保证不出差错,因此,若在编辑程序中,“每接受一个字符即存入用户数据区”的做法显然不是最恰当的.较好的做 法是,设立一个输入缓冲区,用以接受用户输入的一行字符,然后逐行存入用户数据区.允许用户输入出差错,并在发现有误时可以及时更正.例如,当