数据结构--稀疏矩阵转置(列序递增算法)的c语言实现(超详细注释/实验报告)

数据结构–稀疏矩阵转置(列序递增算法)的c语言实现(超详细注释/实验报告)

知识小回顾

稀疏矩阵是指矩阵中大多数元素为零的矩阵。从直观上讲,当非零元素个数低于总元素的30%时,这样的矩阵为稀疏矩阵。

稀疏矩阵的三元组表表示方法

对于稀疏矩阵的压缩存储,采取只存储非零元素的方法。由于系数矩阵中非零元素 a i j a_{ij} aij的分布没有规律,因此,在存储非零元素值的同时,还必须存储该非零元素在矩阵中所处的行号和列号的位置信息,这就是稀疏矩阵的三元组表表示方法。

实验题目

  1. 稀疏矩阵采用三元组顺序表的存储结构
  2. 能够实现按列序递增进行转置
  3. 输出矩阵转置前后的三元组

实验目的

  1. 了解压缩存储的基本原理
  2. 了解稀疏矩阵的三元组表的压缩存储方法
  3. 熟悉三元组表表示的稀疏矩阵运算的实现

实验要求

  1. 稀疏矩阵的三元组表示法及三元组表示的矩阵的转置的实现
  2. 三元组表示的稀疏矩阵相关运算的实现

实验内容和实验步骤

1.需求分析

 实现用户输入一个三元组表,程序将其转置并输出。

2. 概要设计

 设计一个函数实现转置操作,在主函数中让用户输入并输出结果。

3. 详细设计

导入库并定义三元组和三元组表的基本类型

#include<stdio.h>
#define MAXSIZE 20
typedef struct
{
    int row,col,val;//非零元素的行下表和列下标以及值
}TriNode;

typedef struct
{
    TriNode data[MAXSIZE+1];//非零元素的三元组表。data[0]未用
    int m,n,len;//矩阵的行数、列数及非零元素个数
}TriTable;

稀疏矩阵列序递增转置的函数

//稀疏矩阵列序递增转置
void Transpose(TriTable A,TriTable *B)s
{
    int i,j,k;
    B->m=A.n;
    B->n=A.m;
    B->len=A.len;//行数、列数交换,长度还都是相等的
//    printf("%d %d %d\n",B->m,B->n,B->len);
    if(B->len>0)
    {
        j=1;//j为辅助计数器,记录转置后三元组在三元组B中的下标值
        for(k=1;k<=A.n;k++)
        {
            for(i=1;i<=A.len;i++)
            {
                if(A.data[i].col==k)
                {
                    B->data[j].col=A.data[i].row;
                    B->data[j].row=A.data[i].col;
                    B->data[j].val=A.data[i].val;
                    j++;
                }
            }
        }
    }
}

主函数部分

  • 这里就是让用户输入需要转置的矩阵的相关信息,然后调用矩阵转置的函数,并输出转置后的矩阵。
int main()
{
    TriTable s;
    printf("请输入稀疏矩阵的行数、列数和非零元素个数(以空格隔开):");
//    scanf("%d",&s.m);
//    scanf("%d",&s.n);
//    scanf("%d",&s.len);
    scanf("%d%d%d",&s.m,&s.n,&s.len);
//    printf("%d%d%d",s.m,s.n,s.len);
    if(s.len==0)
        return 0;
    int val;
    val=s.len;
    int i;
    for(i=1;i<=val;i++)
    {
        printf("第%d个元素<行号,列号,值>:",i);
        scanf("%d%d%d",&s.data[i].row,&s.data[i].col,&s.data[i].val);
    }
//    printf("%d",s.data[2].val);
    printf("转置前的三元组<行号,列号,值>:\n");
    for(i=1;i<=s.len;i++)
    {
        printf("%d ,%d ,%d \n",s.data[i].row,s.data[i].col,s.data[i].val);
    }
    TriTable t;
    Transpose(s,&t);
    printf("转置后的三元组<行号,列号,值>:\n");
    for(i=1;i<=t.len;i++)
    {
        printf("%d ,%d ,%d \n",t.data[i].row,t.data[i].col,t.data[i].val);
    }
    return 0;
}

4. 调试分析

遇到的问题及解决方法
  • 一开始发现列数为矩阵最大列数的三元组无法转置,后来发现时条件判断中的<=误写成了<
算法的时空分析

算法已经实现了压缩存储,故空间复杂度相比于普通存储节省了不少。
算法的时间耗费主要是在双重循环中,其时间复杂度为 O ( A . n ∗ A . l e n ) O(A.n*A.len) O(A.nA.len)。最坏情况是当矩阵中全部是非零元素时,这个时候时间复杂度为 O ( A . m ∗ A . n 2 ) O(A.m*A.n^2) O(A.mA.n2)若采用经典算法实现矩阵转置的算法时间复杂度为 O ( A . m ∗ A . n ) O(A.m*A.n) O(A.mA.n)。因此,三元组表表示法

实验结果

在这里插入图片描述

实验指导中没有编写函数,我是结合课本和实验指导,写了一个转置的函数出来,这样使得程序的可移植性更强,并为后面编写一次定位快速转置做准备!

实验总结

顺序串需要注意的细节很多,多多重复,百炼成钢!

最后附上完整的代码

#include<stdio.h>
#define MAXSIZE 20
typedef struct
{
    int row,col,val;//非零元素的行下表和列下标以及值
}TriNode;

typedef struct
{
    TriNode data[MAXSIZE+1];//非零元素的三元组表。data[0]未用
    int m,n,len;//矩阵的行数、列数及非零元素个数
}TriTable;

//稀疏矩阵列序递增转置
void Transpose(TriTable A,TriTable *B)s
{
    int i,j,k;
    B->m=A.n;
    B->n=A.m;
    B->len=A.len;//行数、列数交换,长度还都是相等的
//    printf("%d %d %d\n",B->m,B->n,B->len);
    if(B->len>0)
    {
        j=1;//j为辅助计数器,记录转置后三元组在三元组B中的下标值
        for(k=1;k<=A.n;k++)
        {
            for(i=1;i<=A.len;i++)
            {
                if(A.data[i].col==k)
                {
                    B->data[j].col=A.data[i].row;
                    B->data[j].row=A.data[i].col;
                    B->data[j].val=A.data[i].val;
                    j++;
                }
            }
        }
    }
}

int main()
{
    TriTable s;
    printf("请输入稀疏矩阵的行数、列数和非零元素个数(以空格隔开):");
//    scanf("%d",&s.m);
//    scanf("%d",&s.n);
//    scanf("%d",&s.len);
    scanf("%d%d%d",&s.m,&s.n,&s.len);
//    printf("%d%d%d",s.m,s.n,s.len);
    if(s.len==0)
        return 0;
    int val;
    val=s.len;
    int i;
    for(i=1;i<=val;i++)
    {
        printf("第%d个元素<行号,列号,值>:",i);
        scanf("%d%d%d",&s.data[i].row,&s.data[i].col,&s.data[i].val);
    }
//    printf("%d",s.data[2].val);
    printf("转置前的三元组<行号,列号,值>:\n");
    for(i=1;i<=s.len;i++)
    {
        printf("%d ,%d ,%d \n",s.data[i].row,s.data[i].col,s.data[i].val);
    }
    TriTable t;
    Transpose(s,&t);
    printf("转置后的三元组<行号,列号,值>:\n");
    for(i=1;i<=t.len;i++)
    {
        printf("%d ,%d ,%d \n",t.data[i].row,t.data[i].col,t.data[i].val);
    }
    return 0;
}
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值