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

/*******************行逻辑链接的顺序表*****************/
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXSIZE 12500   /// 假设非零元个数最大值为12500
#define MAXRC 12500      ///假设的每行的个数的最大值12500
#define ERROR -1
typedef struct {
    int     i,j;        ///  该非零元的行下标和列下标
    int    e;
}Triple;
typedef struct {
    Triple data[MAXSIZE + 1];///非零元三元组表
    int rpos[MAXRC + 1]; ///各行第一个非零元的位置表
    /*
    以矩阵N为例
    rpos[row]指示矩阵N的第row行中第一个非零元在N.data中的序号,则rpos[row+1]-1指示矩阵N的
    第row行中最后一个非零元在N.data中的序号,最后一个非零元在N.data中的位置显然就是N.tu了。
    也就是说rpos里存的就是各行第一个非零元序号。
    */
    int mu,nu,tu;   ///矩阵的行数、列数和非零元个数
}RLSMatrix;
void ScanfRLSMatrix(RLSMatrix &M){
    int x=0,k=1;
    M.tu = 0;
    for(int i=1;i<=M.mu;i++){
        for(int j=1;j<=M.nu;j++){
            scanf("%d",&x);
            if(x!=0){
                M.data[k].e = x;
                M.data[k].i=i;
                M.data[k].j=j;
                k++;
                M.tu++;
            }
        }
    }
    ///求出rpos的值
    int num[MAXSIZE + 1];
    if(M.tu){
        for(int row=1; row<=M.mu; ++row)  num[row]=0; ///清零
        for(int t=1; t<=M.tu; ++t) ++num[M.data[t].i];  ///求M中每一列含非零个数
        M.rpos[1]=1;
        /// 求第col列中第一个非零元在b.data中的序号
        for(int row =2; row <= M.mu; ++row) M.rpos[row] = M.rpos[row - 1] + num[row - 1];
    }
    /**
    这个求法在快速转置中也用到了,那个求的是每一列的第一个非零元的恰到位置
    这个改一下
    */
}
void PrintfRLSMatrix(RLSMatrix M){
    printf("当前矩阵为:\n");
    int k=1;
    for(int i=1;i<=M.mu;i++){
        for(int j=1;j<=M.nu;j++){
            if(M.data[k].i==i &&M.data[k].j==j ){
                printf("%3d",M.data[k].e);
                k++;
            }
            else printf("%3d",0);
        }
        puts("");
    }
    return ;
}

/*************算法5.3************/
int MultSMareix(RLSMatrix M,RLSMatrix N,RLSMatrix &Q){
    ///求矩阵乘积Q=M*N,采用行逻辑链接存储表示
    if(M.nu != N.mu) return ERROR;
    Q.mu = M.mu; Q.nu = N.nu; Q.tu=0;           ///Q初始化
    int ctemp = 0;  ///定义累加器
    if(M.tu * N.tu != 0){   ///Q是非零矩阵
        for(int arow = 1; arow <= M.mu; ++arow){    ///处理M的每一行
            int ctemp[500];
            memset(ctemp,0,sizeof(ctemp));      ///当前行个元素累加器清零
            Q.rpos[arow]=Q.tu+1;
            int tp=0;       ///定义的矩阵M每一行最后一个非零元的下一个序号
            if(arow < M.mu)  tp = M.rpos[arow + 1];
            else { tp = M.tu + 1; }
            /**
            前mu行,矩阵M每行最后一个非零元素是M.rpos[arow + 1]-1;
            第mu行,矩阵M每行最后一个非零元素是M.tu;
            */
            for(int p =  M.rpos[arow]; p < tp; ++p){    ///便利当前行的每一个非零元素
                int brow = M.data[p].j; ///找到对应元在N中的行号
                int t = 0;
                ///和上面的tp同理,定义矩阵N每一行最后一个非零元的下一个序号
                if(brow < N.mu) t = N.rpos[brow + 1];
                else { t = N.tu + 1; }
                for(int q = N.rpos[brow]; q < t; ++q){
                    int ccol = N.data[q].j;     ///乘积元素在Q中的列号
                    ctemp[ccol] += M.data[p].e * N.data[q].e;
                }//for q
            }/// 求得Q中的第crow( = arow)行的非零元
            /**
            就是M行的第一个非零元,去乘矩阵N的相对应的列q的每一个非零元
            结果存储在ctemp数组中。
            当矩阵M该行的每一个非零元p都乘完,
            此时ctemp数组里存储的就是Q中第一行所有非零元(含零)的结果
            */
            for(int i=0;i<=4;i++)
            printf("%d   ",ctemp[i]);
            printf("\n");
            for(int ccol = 1; ccol <= Q.nu; ++ccol)
                /// 压缩存储该非零元,即把上面求得结果为0的元素去掉
                if(ctemp[ccol]){
                    if( ++Q.tu > MAXSIZE) return ERROR; ///这种情况基本没有
                    Q.data[Q.tu].i = arow;
                    Q.data[Q.tu].j = ccol;
                    Q.data[Q.tu].e = ctemp[ccol];
                }// if
        }// for arow
    }// if
}// MultSMareix

int main()
{
    ///输入稀疏矩阵M
    RLSMatrix M;
    printf("请输入稀疏M的矩阵行mu和列nu:");
    scanf("%d%d",&M.mu,&M.nu);
    ScanfRLSMatrix(M);
    PrintfRLSMatrix(M);

    ///输入稀疏矩阵N
    RLSMatrix N;
    printf("请输入稀疏N的矩阵行mu和列nu:");
    scanf("%d%d",&N.mu,&N.nu);
    ScanfRLSMatrix(N);
    PrintfRLSMatrix(N);

    RLSMatrix Q;
    ///测试行逻辑链接存储的矩阵相乘
    MultSMareix(M,N,Q);
    printf("结果是:\n");
    PrintfRLSMatrix(Q);

    return 0;
}

时间: 2024-10-25 19:12:56

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

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

#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,

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

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

行逻辑链接的矩阵乘法

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

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

稀疏矩阵(三元组,行逻辑连接) 本次代码将关于基本三元组和行逻辑链接表示的三元组进行了封装,还附加了两个系数矩阵的乘法和加法,欢迎大家参考测试代码. #pragma once #include <iostream> #include <queue> #include <vector> #define MAXSIZE 100 using namespace std; typedef struct node { int val; int row; int col; node

算法数据结构 单链表的实现+操作 以及和顺序表的对比

顺序表和单链表的优缺点对比: 顺序表的优点,无需为表示表中元素之间的逻辑关系而增加额外的存储空间: 可以快速的存取表中的任意位置的元素. 顺序表的缺点,插入后删除操作需要移动大量元素: 当线性表长度不稳定时,存储空间难确定,容易造成存储空间碎片. 对于单链表 链式存储即元素存储的内存单元可以是不连续,分散的.对于元素间如何来维护他们的关系(即逻辑结构,每个元素的前驱和后继.) 即用到一个指针域来存储他和前驱或是后继直接的关系. 如上面的是一个单链表的指针结构,即每个元素中存储了他的后继元素的内存

DS|数据结构||第五章小结

本章主要学习了树和二叉树相关知识,包括二叉树的性质和存储结构(双亲表示法.孩子表示法.孩子兄弟法),二叉树的前.中.后序遍历算法等,还了解了哈夫曼树和哈夫曼编码的构造方法,以及森林与二叉树之间的相互转换方法. 实验课老师带领我们做了“深入虎穴”这道题: 7-2 深入虎穴 (30 分) 著名的王牌间谍 007 需要执行一次任务,获取敌方的机密情报.已知情报藏在一个地下迷宫里,迷宫只有一个入口,里面有很多条通路,每条路通向一扇门.每一扇门背后或者是一个房间,或者又有很多条路,同样是每条路通向一扇门…

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

#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

(数据结构第五章)广义表的头尾链表存储表示

/*********广义表的头尾链表存储表示**************/ #include<cstdio> #include<algorithm> using namespace std; typedef int AtomType; ///定义AtomType为int类型 typedef enum { ATOM, LIST } ElemTag; ///ATOM==0; 原子,LIST==1:子表 typedef struct FLNode { ElemTag tag; ///公共

[数据结构]第五章习题作业

1. 已知下图是一个森林的孩子-兄弟表示法的存储结构,画出这个森林的逻辑图. A B C D E F G H I J 2. 下面的二叉树,请为它建立中序遍历线索.已知一指针p指向E,问从p出发利用线索找到E的第4个后继节点,需要访问几次二叉树的节点(重复访问的也计算在内,E点不算)? 3. 已知一个二叉树的先序遍历结果是:a b d e g c f h,中序遍历的结果是:d b e g a c h f .问后序遍历的结果将是什么? 4. 将数组13,5,10 ,7,27,9,4,15,33,20