稀疏矩阵的三元组链表

合集下载

输出稀疏矩阵的三元组表的总结与反思

输出稀疏矩阵的三元组表的总结与反思

输出稀疏矩阵的三元组表的总结与反思
近年来,随着稀疏矩阵在计算机科学中的广泛应用,输出稀疏矩阵的三元组表成为了一种常见的数据结构。

三元组表是将稀疏矩阵以行、列、数值的形式存储在一个二维数组中,可以大大减少稀疏矩阵的存储空间,提高计算效率。

在输出稀疏矩阵的三元组表过程中,需要注意以下几点:
1. 三元组表的行数应为非零元素的个数加一,列数固定为3。

2. 需要按照行优先的顺序输出非零元素的行、列和数值。

3. 输出完所有的非零元素后,需要在三元组表的最后一行输出稀疏矩阵的行数、列数和非零元素的个数。

4. 三元组表的输出格式可以根据需要进行调整,可以使用空格或制表符进行分隔,也可以使用换行符进行换行。

在实际应用中,三元组表的输出结果往往需要进行存储或传输,因此需要考虑输出结果的压缩和解压缩。

其中,压缩方法包括利用行压缩法和列压缩法对三元组表进行压缩,以减小存储空间;解压缩方法则是将压缩后的数据进行还原,还原成原始的三元组表。

总之,输出稀疏矩阵的三元组表是一种重要的数据结构,能够大大提高稀疏矩阵的存储效率和计算效率。

在实际应用中,需要根据具体情况选择合适的输出格式和压缩方法,以达到最优的效果。

- 1 -。

稀疏矩阵的三元组顺序表存储表示及其转置算法

稀疏矩阵的三元组顺序表存储表示及其转置算法

稀疏矩阵的三元组顺序表存储表示及其转置算法目录1. 引言1.1 背景和意义1.2 结构概述1.3 目的2. 稀疏矩阵的三元组顺序表存储表示2.1 稀疏矩阵的定义与特点2.2 三元组顺序表的数据结构和实现方式2.3 存储表示的优缺点分析3. 稀疏矩阵转置算法3.1 转置操作的意义与应用场景3.2 基于三元组顺序表的转置算法设计思路3.3 转置算法的具体实现步骤与复杂度分析4. 实验与结果分析4.1 实验设置和数据样本介绍4.2 转置算法在不同稀疏矩阵上的性能评估和结果比较4.3 分析结果及启示与讨论5. 结论与展望5.1 结论总结5.2 存在问题及后续工作展望1. 引言1.1 背景和意义稀疏矩阵是一种在实际问题中经常遇到的特殊矩阵结构,其绝大部分元素为零。

与稠密矩阵相比,稀疏矩阵的存储和计算效率更高。

稀疏矩阵可以应用于图像处理、网络分析、线性代数等领域。

三元组顺序表是一种存储稀疏矩阵的数据结构,通过记录非零元素的行索引、列索引和数值,有效地减少了存储空间。

同时,三元组顺序表也提供了便捷的转置操作方式。

因此,深入掌握稀疏矩阵的三元组顺序表存储表示及其转置算法对于提高稀疏矩阵相关问题的解决效率具有重要意义。

1.2 结构概述本文将从两个方面进行论述。

首先,介绍稀疏矩阵的定义与特点,以及三元组顺序表在存储表示中所采用的数据结构和实现方式。

其次,详细描述了基于三元组顺序表的稀疏矩阵转置算法的设计思路、具体实现步骤和复杂度分析。

1.3 目的本文旨在探究稀疏矩阵的三元组顺序表存储表示及其转置算法,在理论层面上深入分析其原理和优劣,并在实验中验证其性能表现。

通过本文的研究,我们希望能够提供一种高效、灵活且易于实现的方法来处理稀疏矩阵,并为进一步的相关应用提供有价值的启示和参考。

2. 稀疏矩阵的三元组顺序表存储表示2.1 稀疏矩阵的定义与特点稀疏矩阵是指在一个二维矩阵中,大部分元素都为0的情况下,只有少数非零元素的情况。

三元组表示稀疏矩阵

三元组表示稀疏矩阵

三元组表示稀疏矩阵本节介绍稀疏矩阵三元序列表的压缩存储方式。

通过《矩阵的压缩存储》一节我们知道,稀疏矩阵的压缩存储,至少需要存储以下信息:•矩阵中各非 0 元素的值,以及所在矩阵中的行标和列标;•矩阵的总行数和总列数;图 1 稀疏矩阵示意图例如,图 1 是一个稀疏矩阵,若对其进行压缩存储,矩阵中各非 0 元素的存储状态如图 2 所示:图 2 稀疏矩阵的压缩存储示意图在图2的数组中,存储了一个三元组(即一组三个部分的数据),分别表示组中的数据(行标签、列标签和元素值)。

注意,这里矩阵的行和列标签都是从1开始的。

C 语言中,三元组需要用结构体实现,如下所示://三元组结构体typedef struct {int i,j;//行标i,列标jint data;//元素值}triple;由于稀疏矩阵中非 0 元素有多个,因此需要建立 triple 数组存储各个元素的三元组。

除此之外,考虑到还要存储矩阵的总行数和总列数,因此可以采用以下结构表示整个稀疏矩阵:#define number 20//矩阵的结构表示typedef struct {triple data[number];//存储该矩阵中所有非0元素的三元组int n,m,num;//n和m分别记录矩阵的行数和列数,num 记录矩阵中所有的非0元素的个数}TSMatrix;可以看到,TSMatrix 是一个结构体,其包含一个三元组数组,以及用于存储矩阵总行数、总列数和非 0 元素个数的变量。

假设采用 TSMatrix 结构体存储图 1 中的稀疏矩阵,其 C 语言实现代码应该为:#include<stdio.h>#define number 3typedef struct {int i,j;int data;}triple;typedef struct {triple data[number];int n,m,num;}TSMatrix;//输出存储的稀疏矩阵void display(TSMatrix M);int main() {TSMatrix M;M.m=3;M.n=3;M.num=3;M.data[0].i=1;M.data[0].j=1;M.data[0].data=1;M.data[1].i=2;M.data[1].j=3;M.data[1].data=5;M.data[2].i=3;M.data[2].j=1;M.data[2].data=3;display(M);return 0;}void display(TSMatrix M){for(int i=1;i<=M.n;i++){for(int j=1;j<=M.m;j++){int value =0;for(int k=0;k<M.num;k++){if(i == M.data[k].i && j ==M.data[k].j){printf("%d ",M.data[k].data); value =1;break;}}if(value == 0)printf("0 ");}printf("\n");}}输出结果为:1 0 00 0 53 0 0。

实验5稀疏矩阵三元组表的操作1

实验5稀疏矩阵三元组表的操作1

实验五稀疏矩阵三元组表的操作科目:数据结构实验和课程设计班级: 10信管姓名:徐杨学号:2010110450 实验目的:会定义稀疏矩阵的三元组表。

熟悉C语言程序的基本结构,掌握程序中的用户头文件、文件之间的相互关系及各自的作用。

熟悉对稀疏矩阵的三元组表的一些基本操作和具体的函数定义。

熟悉C语言操作环境的使用以及多文件程序的输入、编辑、调试和运行的全过程。

实验要求:认真阅读和掌握本实验内容所给的全部程序。

保存和输出程序运行结果,并结合程序进行分析。

按照你对稀疏矩阵的三元组表操作的需要,编写程序代码然后运行,给出运行结果。

实验设备:每人一台安装VC6.0编写软件的计算机,公用打印机。

注意事项:要在硬盘上建立好自己的工作目录,专门用来存储自己所做的实验程序及相关数据,以后每次做实验最好仍采用这个目录。

认真编写算法及运行结果,针对本实验的具体算法,认真写出算法分析。

一、实验步骤:#include<iostream.h>//稀疏矩阵三元组表的操作#define maxsize 64#define M#define Ntypedef int elemtype;struct node{int r,c;elemtype d;};struct ts{int rows,cols,nums;node data[maxsize];};void create(ts &a);//稀疏矩阵三元组表的建立void disp(ts a);//显示稀疏矩阵三元组表的内容void trants(ts a,ts &at); //求稀疏矩阵的转置void add(ts a,ts b,ts &c);//求两稀疏矩阵的和void main(){ts a;create(a); //稀疏矩阵三元组表的建立disp(a); //显示稀疏矩阵三元组表的内容ts at;trants(a,at); //求稀疏矩阵的转置disp(at); //显示转置矩阵的内容ts b;create(b);disp(b); //稀疏矩阵三元组表的建立ts c;add(a,b,c); //求两稀疏矩阵的和disp(c); //显示两稀疏矩阵和的内容}void create(ts &a) //稀疏矩阵三元组表的建立{ cout<<"建立稀疏矩阵三元组表:"<<endl;cout<<"稀疏矩阵的行数为:";cin>>a.rows;cout<<"稀疏矩阵列的数为:";cin>>a.cols;cout<<"稀疏矩阵中非零的元素个数为:";cin>>a.nums;cout<<"稀疏矩阵的三元组表为:"<<endl;for(int i=0;i<a.nums;i++){cin>>a.data[i].r>>a.data[i].c>>a.data[i].d;}}void disp(ts a) //显示稀疏矩阵三元组表的内容{ int i;cout<<"显示稀疏矩阵三元组表:"<<endl;if(a.nums<=0) return;cout<<"行数为:"<<a.rows<<" "<<"列数为:"<<a.cols<<" "<<"元素个数为:"<<" "<<a.nums<<endl;cout<<"------------------------"<<endl;for(i=0;i<a.nums;i++)cout<<a.data[i].r<<" "<<a.data[i].c <<" "<<a.data[i].d <<endl;}void trants(ts a,ts &at)//求稀疏矩阵的转置{ int p,q=0,v;at.rows=a.cols;at.cols=a.rows;at.nums=a.nums;if(a.nums!=0){ for(v=0;v<a.cols;v++)for(p=0;p<a.nums;p++)if(a.data[p].c==v){at.data[q].r=a.data[p].c;at.data[q].c=a.data[p].r;at.data[q].d=a.data[p].d;q++;}}cout<<"转置后的稀疏矩阵:"<<endl;}void add(ts a,ts b,ts &c) //求两稀疏矩阵的和{int i=0,j=0,k=0;elemtype v;if (a.rows!=b.rows||a.cols!=b.cols)c.rows=a.rows;c.cols=a.cols;while (i<a.nums&&j<b.nums){if(a.data[i].r==b.data[j].r){if(c.data[i].c<b.data[j].c){c.data[k].r=a.data[i].r;c.data[k].c=a.data[i].c;c.data[k].d=a.data[i].d;k++;i++;}else if(a.data[i].c>b.data[j].c){c.data[k].r=b.data[j].r;c.data[k].c=b.data[j].c;c.data[k].d=b.data[j].d;k++;j++;}else{v=a.data[i].d+b.data[j].d;if(v!=0){c.data[k].r=a.data[i].r;c.data[k].c=a.data[i].c;c.data[k].d=v;k++;}i++;j++;}}else if(a.data[i].r<b.data[j].r){c.data[k].r=a.data[i].r;c.data[k].c=a.data[i].c;c.data[k].d=a.data[i].d;k++;i++;}else{c.data[k].r=b.data[j].r;c.data[k].c=b.data[j].c;c.data[k].d=b.data[j].d;k++;j++;}c.nums=k;}cout<<"两个稀疏矩阵求和后元素的个数为:"<<c.nums<<endl; }二、运行结果:三、算法分析:。

稀疏矩阵——三元组顺序表

稀疏矩阵——三元组顺序表

稀疏矩阵——三元组顺序表⽬录稀疏矩阵假设m*n的矩阵中,有t的⾮零元,令s=t/m * n,当,s<=0.05时,称此矩阵为稀疏矩阵,简单理解就是⾮零元特别少的矩阵//⼀般矩阵a1 2 3a= 4 5 67 8 9//稀疏矩阵s0 0 0 0 00 2 0 0 5s= 0 0 3 0 00 0 0 0 4矩阵的转置⼀个m * n的矩阵转置后变为 n * m的矩阵//3*2的矩阵-转置前1 24 57 8//转置后变为2*31 4 72 5 8转置后的矩阵每个元素的下表与原来的下表刚好相反,例如上⾯4转置前的下标为(2,1),转置后变为(1,2);矩阵压缩存储-三元组顺序表之所以引⼊三元组顺序表,是因为,对于稀疏矩阵⽽⾔,⽤传统的存储⽅法会造成存储空间的浪费0 12 9 0 0 0 00 0 0 0 0 0 0-3 0 0 0 0 14 0M= 0 0 24 0 0 0 00 18 0 0 0 0 015 0 0 -7 0 0 0//上⾯矩阵⽤三元组表⽰i j v1 2 121 3 93 1 -33 6 144 3 245 2 186 1 156 4 -7typedef struct{int i,j; //⾏坐标、列坐标ElemType e; //元素}Triple;typedef struct{Triple date[MAXSIZE+1]; //0不存储元素int mu,nu,tu; //⾏数、列数、⾮零元个数}TSMatrix;稀疏矩阵的转置传统⽅法的转置算法时遍历矩阵的每⼀项,交换其下标值即可for(col=1;col<=nu;col++){for(row=1;row<=mu;row++){T[col][row]=M[row][col]}}//时间复杂度 : O(nu*mu)利⽤三元组顺序表进⾏存储的稀疏矩阵要想实现转置显然不能⽤上⾯的算法,下⾯介绍两种⽅法:第⼀种:以列序为主序的转置//置换前存储位置i j v1 2 12 -> M.date[1]1 3 9 -> M.date[2]3 1 -3 -> M.date[3]3 6 14 -> M.date[4]4 3 24 -> M.date[5]5 2 18 -> M.date[6]6 1 15 -> M.date[7]6 4 -7 -> M.date[8]//置换后存储位置i j v1 3 -3 -> T.date[1]1 6 15 -> T.date[2]2 1 12 -> T.date[3]2 5 18 -> T.date[4]3 1 9 -> T.date[5]3 4 24 -> T.date[6]4 6 -7 -> T.date[7]6 3 14 -> T.date[8]void TransposeSMatrix(TSMatrix *T1,TSMatrix *T2){T2->mu=T1->nu;T2->nu=T1->mu;T2->tu=T1->tu;if(T1->tu){int q=1,col,p;for(col=1;col<=T1->nu;col++) //矩阵列循环{for(p=1;p<=T1->tu;p++) //遍历所有元素{if(T1->date[p].j==col) //当元素在col列时{T2->date[q].i=T1->date[p].j;T2->date[q].j=T1->date[p].i;T2->date[q].e=T1->date[p].e;q++;}}}}}//上述代码,当矩阵运算为满时,即tu=mu*nu,其时间复杂度为O(nu*nu*mu)//这种情况与经典算法相⽐,虽节省了存储空间,但是效率较低第⼆种:快速转置第⼀种算法是通过遍历所有元素的下标,从⽽确定其在转置后数组中的位置,快速转置的思想就是,预先确定每⼀列第⼀个⾮零元在对应转置后的数组date中的位置;因此需要两个辅助数组num[]:⽤来存放每⼀列的⾮零元个数cpot[]:存放第⼀个⾮零元在转置后数组date中的位置num[]数组的值很好求,只需要遍历⼀次所有元素即可for(t=1;t<=T1->tu;t++)++num[T1->date[t].j];对于cpot[],有⼀个规律col 1 2 3 4 5 6 7num[col] 2 2 2 1 0 1 0cpot[col] 1 3 5 7 8 8 9//规律copt[1]=1copt[col]=copt[col-1]+num[col-1]代码:void FastTransposeSMatrix(TSMatrix *T1,TSMatrix *T2){int num[T1->nu],cpot[T1->nu];int col,p,q,t;T2->mu=T1->nu;T2->nu=T1->mu;T2->tu=T1->tu;if(T1->tu){//初始化每列⾮零元个数为0for(col=1;col<=T1->nu;col++){num[col]=0;}//求每列⾮零元个数for(t=1;t<=T1->tu;t++){++num[T1->date[t].j];}//求每列第⼀个⾮零元转置后的位置cpot[1]=1;for(col=2;col<=T1->nu;col++){cpot[col]=num[col-1]+cpot[col-1];}//遍历所有元素for(p=1;p<=T1->tu;p++){col=T1->date[p].j; //获取列坐标q=cpot[col]; //获取新位置T2->date[q].i=T1->date[p].j;T2->date[q].j=T1->date[p].i;T2->date[q].e=T1->date[p].e;++cpot[col]; //之所以这个地⽅要++,因为每列⾮零元可能不⽌⼀个 }}}完整代码:#include <stdio.h>#include <stdlib.h>#define MAXSIZE 12500 //⾮零元个数的最⼤值typedef int ElemType;typedef struct{int i,j;ElemType e;}Triple;typedef struct{Triple date[MAXSIZE+1];int mu,nu,tu;}TSMatrix;//输⼊元素void Insert(TSMatrix *T){printf("请依次输⼊⾏数i、列数j、⾮零元个数sum:\n");int sum ;scanf("%d%d%d",&T->mu,&T->nu,&sum);T->tu=sum;int x,y,num;printf("请依次输⼊矩阵⾮零元的⾏坐标i、列坐标j、元素值x:\n");printf("i j v\n");for(int i=1 ;i<=sum;i++){scanf("%d%d%d",&x,&y,&num);T->date[i].i=x;T->date[i].j=y;T->date[i].e=num;}}//第⼀种转置⽅法void TransposeSMatrix(TSMatrix *T1,TSMatrix *T2)T2->mu=T1->nu;T2->nu=T1->mu;T2->tu=T1->tu;if(T1->tu){int q=1,col,p;for(col=1;col<=T1->nu;col++){for(p=1;p<=T1->tu;p++){if(T1->date[p].j==col){T2->date[q].i=T1->date[p].j;T2->date[q].j=T1->date[p].i;T2->date[q].e=T1->date[p].e;q++;}}}}}//输出矩阵⾮零元void Show(TSMatrix *T){printf("转置后的矩阵:\n");printf("i j v\n");for(int i=1;i<=T->tu;i++){printf("%d %d %d\n",T->date[i].i,T->date[i].j,T->date[i].e); }}//快速转置void FastTransposeSMatrix(TSMatrix *T1,TSMatrix *T2){int num[T1->nu],cpot[T1->nu];int col,p,q,t;T2->mu=T1->nu;T2->nu=T1->mu;T2->tu=T1->tu;if(T1->tu){//初始化每列⾮零元个数为0for(col=1;col<=T1->nu;col++){num[col]=0;}//求每列⾮零元个数for(t=1;t<=T1->tu;t++){++num[T1->date[t].j];}cpot[1]=1;for(col=2;col<=T1->nu;col++){cpot[col]=num[col-1]+cpot[col-1];}for(p=1;p<=T1->tu;p++){col=T1->date[p].j;q=cpot[col];T2->date[q].i=T1->date[p].j;T2->date[q].j=T1->date[p].i;T2->date[q].e=T1->date[p].e;++cpot[col];}}}int main(){TSMatrix T,T1,*q,*p;p=&T;q=&T1;Insert(p);//测试第⼀种转置⽅法TransposeSMatrix(p, q);Show(q);//测试快速转置FastTransposeSMatrix(p, q);Show(q);}/* 测试请依次输⼊⾏数i、列数j、⾮零元个数sum:6 7 8请依次输⼊矩阵⾮零元的⾏坐标i、列坐标j、元素值x:1 2 121 3 93 1 -33 6 144 3 245 2 186 1 156 4 -7转置后的矩阵:i j v1 3 -31 6 152 1 122 5 183 1 93 4 244 6 -76 3 14转置后的矩阵:i j v1 3 -31 6 152 1 122 5 183 1 93 4 244 6 -76 3 14Program ended with exit code: 0*/我不⽣产代码,我只是代码的搬运⼯。

用三元组表示稀疏矩阵的乘法

用三元组表示稀疏矩阵的乘法

该结点除了( row , col , value )以外,还要有以下两个链域:
right: down: 用于链接同一列中的下一个非零元素。
row Down
col
Value right
第十二讲
1 1 3
1 4 5
2 2 -1
3 1 3
图5.23 十字链表的结构
第十二讲
十字链表的结构类型说明如下:
typedef struct OLNode
第十二讲
用三元组表实现稀疏矩阵的乘法运算
第十二讲
两个矩阵相乘也是矩阵的一种常用的运算。设矩阵 M 是
m1×n1 矩阵, N 是 m2×n2 矩阵;若可以相乘,则必须满足矩
阵 M 的列数 n1 与矩阵 N 的行数 m2 相等,才能得到结果矩阵 Q=M×N(一个m1×n2的矩阵)。
数学中矩阵Q中的元素的计算方法如下:
矩阵不仅节约了空间,而且使得矩阵某些运算的运算时间比经
典算法还少。但是在进行矩阵加法、减法和乘法等运算时,有 时矩阵中的非零元素的位置和个数会发生很大的变化。如
A=A+B, 将矩阵B加到矩阵A上,此时若还用三元组表表示法,
势必会为了保持三元组表“以行序为主序”而大量移动元素。
第十二讲
在十字链表中,矩阵的每一个非零元素用一个结点表示,
0 1 N 2 0
2 0 4 0
0 Q 1 0
6 0 4
图5.17 Q=M×N
第十二讲
图5.18 矩阵M、N、Q的三元组表
第十二讲
经典算法中,不论 M [ i ][ k ]、 N [ k ][ j ]是否为零,
for(k=1; k<=n1; k++)

三元组表示稀疏矩阵的转置(一般算法和快速算法)

三元组表示稀疏矩阵的转置(一般算法和快速算法)

一、设计要求1.1 问题描述稀疏矩阵是指那些多数元素为零的矩阵。

利用稀疏特点进行存储和计算可以大大节省存储空间,提高计算效率。

求一个稀疏矩阵A的转置矩阵B。

1.2需求分析(1)以“带行逻辑链接信息”的三元组顺序表表示稀疏矩阵,实现稀疏矩阵的转置运算。

(2)稀疏矩阵的输入形式采用三元组表示,运算结果则以通常的阵列形式列出。

(3)首先提示用户输入矩阵的行数、列数、非零元个数,再采用三元组表示方法输入矩阵,然后进行转置运算,该系统可以采用两种方法,一种为一般算法,另一种为快速转置算法。

(4)程序需要给出菜单项,用户按照菜单提示进行相应的操作。

二、概要设计2.1存储结构设计采用“带行逻辑链接信息”的三元组顺序表表示矩阵的存储结构。

三元组定义为:typedef struct{int i;//非零元的行下标int j;//非零元的列下标ElemType e; //非零元素值}Triple;矩阵定义为:Typedef struct{Triple data[MAXSIZE+1]; //非零元三元组表int rpos[MAXRC+1]; //各行第一个非零元的位置表int mu,nu,tu; //矩阵的行数、列数和非零元个数}RLSMatrix;例如有矩阵A,它与其三元组表的对应关系如图2.2 系统功能设计本系统通过菜单提示用户首先选择稀疏矩阵转置方法,然后提示用户采用三元组表示法输入数据创建一个稀疏矩阵,再进行矩阵的转置操作,并以通常的阵列形式输出结果。

主要实现以下功能。

(1)创建稀疏矩阵。

采用带行逻辑连接信息的三元组表表示法,提示用户输入矩阵的行数、列数、非零元个数以及各非零元所在的行、列、值。

(2)矩阵转置。

<1>采用一般算法进行矩阵的转置操作,再以阵列形式输出转置矩阵B。

<2>采用快速转置的方法完成此操作,并以阵列形式输出转置矩阵B。

三、模块设计3.1 模块设计程序包括两个模块:主程序模块、矩阵运算模块。

数据结构-稀疏矩阵的三元组表存储方法

数据结构-稀疏矩阵的三元组表存储方法

0 0 -3 0 0 15
0 12 9 0 0 0 0
12 0 0 0 18 0
00 00000
9 0 0 24 0 0
M= -3 0 0 0 0 14 0 0 0 24 0 0 0 0
求解 N=
0 0 0 0 0 -7 0000 00
0 18 0 0 0 0 0
0 0 14 0 0 0
15 0 0 0 0 0
4 3 24 5 2 18
注意:
data 7 data 8
6 1 15 6 4 -7
mu=6 nu=7 tu=8
为了保存矩阵的行数、列 数和非零元素个数,还需 增设三个量:mu nu tu
3.三元组线性表的数据类型描述
#define MAXSIZE 12500 //非零元素个数的最大值
typedef struct{
稀疏矩阵的压缩存储 ———三元组表
一、什么是稀疏矩阵(sparse matrix)
如果矩阵M中的大多数元素均 为零元素,则称矩阵M为稀疏矩 阵 。一般地,当非零元素个数 只占矩阵元素总数的25%—30%, 或低于这个百分数时,我们称这样 的矩阵为稀疏矩阵。
一、什么是稀疏矩阵(sparse matrix)
3.算法描述
status TransposeSMatrix(TSMatrix a, TSMatrix *b){ (*b).mu=a.nu; (*b).nu=a.mu; (*b).tu=a.tu; if ((*b).tu) { q= 1; for (col= 1 ; col<= a.nu ; + + col) for (p= 1 ; p<= a.tu ; + +p) if (a.data[p] .j = =col) { b.data[q].i=a.data[p] .j; b.data[q].j=a.data[p] .i; b.data[q].e=a.data[p].e; ++q; } return OK;
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
ype
{ int row;
//行号
int col; ElemType value;
//列号 //元素值
};
例1中的稀疏矩阵的三元组线性表的存储结构 如下图所示
线性结构(包括线性表、堆栈、队列、串)的顺序存储结构实际就是使用数组来 存储。可见,数组是其他数据结构实现顺序存储结构的基础,是软件设计中最基础 的数据结构。
2.数组的实现机制
1、一维数组(n个元素)中任一元素ai的内存单元地址 Loc(ai)=LOC(a0)+i*k (0≤i <n)
a0的内存单元地址
i(i-1)/2+j-1 当i≥j k= n(n+1)/2 (或空) 当i<j
注:此时一维数组sa的数据元素个数为(n(n+1)/2)+1个,其中数组 sa的最后一个位置存储A中数值不为0的那个常数。
5.4 稀疏矩阵
1.概念
1、稀疏矩阵 矩阵中非零元素的个数远远小于矩阵元素个数。
2、稠密矩阵 一个不稀疏的矩阵。
15137 50800 18926 30251
a11 a21 a22 a31 a32 a33 ………………..
70613
an1 an2 an3 …ann
n阶对称矩阵中的元素关于主对角线对称,故只要存储矩阵中上三角或下 三角中的元素,让每两个对称的元素共享一个存储空间,这样,能节约 近一半的存储空间。
5.1 数组的基本概念
1.数组的定义
数组是n(n>1)个相同数据类型的数据元素a0,a1,a2,...,an-1构成的占用一块地址连 续的内存单元的有限序列。
数组中任意一个元素可以用该元素在数组中的位置来表示,数组元素的位置 通常称作数组的下标。
数组符合线性结构的定义。数组和线性表相比,
相同之处是它们都是若干个相同数据类型的数据元素a0,a1,a2,...,a0-1构成的有限序列。 不同之处是: (1)数组要求其元素占用一块地址连续的内存单元空间,而线性表无此要求; (2)线性表的元素是逻辑意义上不可再分的元素,而数组中的每个元素还可以是 一个数组; (3)数组的操作主要是向某个下标的数组元素中存数据和取某个下标的数组元素, 这和线性表的插入、删除操作不同。
源码: Maloctst.c
5.3 特殊矩阵
特殊矩阵:指有许多值相同的元素或有许多零元素、且值相同的元素或零元素的 分布有一定规律的矩阵。
1.几种特殊矩阵的压缩存储:
(1)n阶对称矩阵
在一个n阶方阵A中,若元素满足下述性质: aij=aji (1≤i,j≤n)
则称A为n阶对称矩阵。如图5.1是一个5阶对称矩阵。
A =… … … …
mn am-1,0 am-1,1 … am-1,n-1
一个m×n的二维数组可以看成是m 行的一维数组,或者n列的一维数组。
3.数组抽象数据类型
数据集合: 数组的数据集合可以表示为a0, a1, a2, ..., an-1,每个数据元素的数据类型为抽象数据 元素类型DataType。 操作集合: (1)初始化数组 Initiate(D) (2)取数组元素个数 Size(D) (3)存数组元素 Storage(D,i,x) (4)取数组元素 Get(D, i)
3、稀疏矩阵压缩存储方法 只存储稀疏矩阵中的非零元素,实现方法是:将每个非零元素用一个三元组(i,
j,aij)来表示,则每个稀疏矩阵可用一个三元组线性表来表示。
例1:写出下图5.3所示稀疏矩阵的压缩存储形式。
123456
1
0 12 9 0 0 0
2
0 0 0000
3
-3 0 0 0 14 0
4
5
0 0 24 0 0 0
i(i-1)/2+j-i 当i≥j k= j(j-1)/2+i-1 当i<j
(2)n阶三角矩阵 以主对角线划分, n阶三角矩阵有n阶上三角矩阵和n阶下三角矩阵
两种。 n阶上三角矩阵如下图 (a)所示,它的下三角(不包括主对角线)中的
元素均为0(或常数)。n阶下三角矩阵正好相反,它的主对角线上方均 为0(或常数),如下图 (b)所示。
在这个下三角矩阵中,第i行恰有i个元素,元素总数为n(n+1)/2,这样 就可将n2个数据元素压缩存储在n(n+1)/2个存储单元中。
假设以一维数组va作为n阶对称矩阵A的压缩存储单元,k为一维数组va 的下标序号,aij为n阶对称矩阵A中i行j列的数据元素(其中1≤i,j≤n ),其 数学映射关系为:
5.2 动态数组
数组有静态存储结构的数组和动态存储结构的数组两种,它们的区别在于: 静态数组在定义时就必须给出数组个数; 动态数组是在具体申请存储单元空间时才给出数组元素的个数。
Datatype * p; p = (Datatype *)malloc(sizeof(Datatype)*n) if (NULL == p) {…} … free(p); p = NULL;
每个元素所需的字节个数
2、一个m行n列的二维数组 LOC(aij)=LOC(a00)+(i*n+j)*k (0≤i<m,0≤j<n)
a00的内存单元地址
每个元素所需的字节个数
注:C语言中数组元素采用行主序的存放方法,即行优先顺序。
a0,0 a0,1 … a0,n-1 a1,0 a1,1 … a1,n-1
注:在大多数情况下, n阶三角矩阵常数为零。
a11 a12 … a 1n c a22 … a 2n ……………….
c c … a nn
(a)上三角矩阵
a11 c … c a21 a22 … c ………………
an1 an2 … an n
(b)下三角矩阵
假设以一维数组sa作为n阶下三角矩阵A的压缩存储单元,k为一维数组 va的下标序号,aij为n阶下三角矩阵A中i行j列的数据元素(其中1≤i,j≤n ), 其数学映射关系为:
6
0 18 0 0 0 0
15 0 0 -7 0 0
解:用三元组线性表表示: {{1,2,12},{1,3,9},{3,1,-3},{3,5,14}, {4,3,24},{5,2,18},{6,1,15},{6,4,-7}}
说明:稀疏矩阵的压缩存储结构主要有三元组顺序表和三元组链表两大类型。
(1)三元组顺序表 指用顺序表存储的三元组线性表。
相关文档
最新文档