(10)稀疏矩阵的三元组表存储方法
数据结构之稀疏矩阵稀疏矩阵的存储方式和操作分析

数据结构之稀疏矩阵稀疏矩阵的存储方式和操作分析稀疏矩阵是指矩阵中大部分元素为零的特殊矩阵。
在实际应用中,稀疏矩阵经常出现,如图像处理、网络分析和科学计算等领域。
对于稀疏矩阵的存储和操作是数据结构中的重要内容。
本文将介绍稀疏矩阵的存储方式和相关操作的分析。
一、稀疏矩阵存储方式稀疏矩阵的存储方式有多种,其中三元组顺序表和二维数组是比较常用的方法。
1. 三元组顺序表三元组顺序表是一种基于行优先存储的方式,可以将稀疏矩阵以非零元素的形式存储起来。
主要包括行号、列号和元素值三个信息。
以一个4x5的稀疏矩阵为例,其中有三个非零元素分别为A[1][2]=3, A[2][3]=4, A[3][4]=5。
可以使用三元组顺序表来存储:```行号列号元素值1 2 32 3 43 4 5```三元组顺序表的优点是可以节省存储空间,同时也方便进行矩阵的操作。
但是在进行元素的查找和修改时,效率较低。
2. 二维数组二维数组是一种常见的矩阵表示方法,可以直接使用二维数组来表示稀疏矩阵。
其中非零元素的位置用实际的值表示,其余位置用零值表示。
以同样的4x5的稀疏矩阵为例,使用二维数组存储如下:```0 0 0 0 00 0 3 0 00 0 0 4 00 0 0 0 5```二维数组的优点是简单直观,并且可以快速进行元素的查找和修改。
但当稀疏矩阵的规模较大时,会造成较高的存储资源浪费。
二、稀疏矩阵的操作分析对于稀疏矩阵的操作,主要包括矩阵的转置、相加、相乘等。
1. 转置操作稀疏矩阵的转置是指将原始矩阵的行与列对调。
对于三元组顺序表来说,转置操作主要涉及到行号和列号的交换。
而对于二维数组来说,可以直接在取值的时候将行号和列号对调即可。
2. 相加操作稀疏矩阵的相加操作是指将两个矩阵对应位置的元素相加。
对于三元组顺序表来说,可以通过遍历两个矩阵的非零元素,并将其对应位置的元素相加。
而对于二维数组来说,可以直接将对应位置的元素相加即可。
3. 相乘操作稀疏矩阵的相乘操作是指将两个矩阵相乘得到一个新的矩阵。
三元组表示稀疏矩阵

三元组表示稀疏矩阵本节介绍稀疏矩阵三元序列表的压缩存储方式。
通过《矩阵的压缩存储》一节我们知道,稀疏矩阵的压缩存储,至少需要存储以下信息:•矩阵中各非 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。
稀疏矩阵——三元组顺序表

稀疏矩阵——三元组顺序表⽬录稀疏矩阵假设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*/我不⽣产代码,我只是代码的搬运⼯。
java稀疏矩阵的三元组存储

=====实习报告三“稀疏矩阵的三元组存储”演示程序======(一)、程序的功能和特点1. 程序功能:建立稀疏矩阵的三元组存储,可以键盘输入所要存储的稀疏矩阵,能将输入的稀疏矩阵显示输出。
2. 程序特点:采用java面向对象语言,将三元组和稀疏矩阵用类进行封装。
能方便的储存稀疏,方便的显示稀疏矩阵。
(二)、程序的算法设计算法一:“显示输出稀疏矩阵”算法:1.【逻辑结构与存储结构设计】逻辑结构:线性结构。
存储结构:顺序存储结构。
数组采用三元组顺序存储方法存储该表。
2.【基本操作设计】3.【算法设计】i j v1 1 1 152 1 4 223 1 6 -154 2 2 115 2 3 36 3 4 67 5 1 91 三元组表15 0 0 22 0 -150 11 3 0 0 00 0 0 60 00 0 0 00 091 0 0 00 00 0 0 00 0稀疏矩阵A=开始输出命令输出该稀疏矩阵的行数和列数。
利用for循环按先行后列顺序输出矩阵循环访问稀疏矩阵的每一个元素,通过行号和列号找到稀疏矩阵的在三元组表中是否有存储,若有则输出其值,若没有则输出0.文字说明:(1).首先输出稀疏矩阵的行数和列数。
(2).在通过for 循环依次访问该稀疏矩阵的每一个元素,比较行号和列号,如果行号和列号和三元组所存储的相同,则输出其值;(3).如果不相同或三元数组没有储存则该元素值为零; (4).输出结束。
4.【高级语言代码】 //显示输出稀疏矩阵 void display(){ int i,j,k;System.out .println("稀疏矩阵的行数 "+Rows ); System.out .println("稀疏矩阵的列数 "+Cols ); //按先行后列顺序输出矩阵 for (i=0;i<Rows ;i++) { for (j=0;j<Cols ;j++) {for (k=0;k<Terms ;k++) //查三元组表if (i==smArray [k].row &&j==smArray [k].col ){ System.out .print(smArray [k].value +" "); break ; //打断k 循环 }if (k==Terms ) System.out .print("0.0 "); }System.out .println(); //换行 } }(三)、程序中类的设计“Trituple ”类:1.【逻辑结构与存储结构】 逻辑结构:线性结构。
三元组稀疏矩阵

三元组稀疏矩阵
三元组稀疏矩阵是指矩阵中大部分元素为0,非零元素只占据很小一部分的矩阵。
为了节省存储空间,在表示稀疏矩阵时,通常采用三元组的形式进行存储。
三元组稀疏矩阵的表示方法是将非零元素的值、行号和列号以三元组的形式存储起来。
具体来说,用一个二维数组来表示三元组矩阵,数组的每一行代表一个非零元素,包括三个部分:非零元素的值、行号和列号。
举个例子,假设有一个稀疏矩阵如下:
1 0 0 0
0 0 2 0
0 3 0 0
则可以用三元组稀疏矩阵表示为:
(1, 0, 0)
(2, 1, 2)
(3, 2, 1)
其中,(1, 0, 0)表示非零元素1在第0行第0列,(2, 1, 2)表示非零元素2在第1行第2列,(3, 2, 1)表示非零元素3在第2行第1列。
通过使用三元组表示稀疏矩阵,可以大大减少存储空间的占用,提高矩阵的存储效率。
稀疏矩阵的相关操作

稀疏矩阵的相关操作稀疏矩阵是指在一个矩阵中,大部分元素为0的矩阵。
由于大部分元素为0,而非零元素相对较少,稀疏矩阵的存储和处理具有一定的特殊性。
在实际应用中,经常需要对稀疏矩阵进行各种操作,如创建、存储、加法操作等。
本文将从这些方面详细介绍稀疏矩阵的相关操作。
首先,创建稀疏矩阵需要考虑两个关键因素:矩阵的大小和矩阵的稀疏性。
对于稀疏矩阵的大小,一般可以使用行数和列数来描述。
而对于稀疏矩阵的稀疏性,可以使用一个矩阵的非零元素个数与总元素个数的比值来衡量,一般使用稀疏度来表示,即非零元素个数与总元素个数的比值。
创建稀疏矩阵的方法有多种,下面介绍两种常见的方法。
1.压缩矩阵存储法:该方法将稀疏矩阵的非零元素和对应的行列坐标存储在一个矩阵中。
其中,矩阵的每一行存储一个非零元素的值、行和列坐标。
这种方法虽然节约了存储空间,但是在进行矩阵操作时,需要通过遍历矩阵找到对应的非零元素,因此操作效率较低。
2.链表存储法:该方法将稀疏矩阵的非零元素和对应的行列坐标存储在一个链表中。
链表的每个节点包含一个非零元素的值、行和列坐标,以及下一个非零元素的指针。
这种方法在插入和删除操作时比较方便,并且节约了存储空间。
但是,链表存储法在进行矩阵操作时,也需要通过遍历链表找到对应的非零元素,因此操作效率较低。
除了创建稀疏矩阵,还需要进行其他各种操作,如稀疏矩阵的加法、乘法、转置等。
稀疏矩阵的乘法操作较为复杂。
对于两个稀疏矩阵相乘,需要根据矩阵乘法的定义,将一个矩阵的行与另一个矩阵的列进行乘法运算,然后将结果相加得到最终的乘积矩阵。
由于稀疏矩阵的特殊性,可以采用稀疏矩阵乘法算法进行计算,提高乘法操作的效率。
1.三元组转置法:该方法将稀疏矩阵的非零元素和对应的行列坐标存储在三个数组中,分别是非零元素数组、行坐标数组和列坐标数组。
将这三个数组的元素进行转置,并重新组合成转置后的稀疏矩阵。
2.链表转置法:该方法将稀疏矩阵的非零元素和对应的行列坐标存储在链表中。
(10)稀疏矩阵的三元组表存储方法

求解
b .data 4 b .data 5 b .data 6 b .data 7 b .data 8
a. mu=6 a. nu=7 a. tu=8
注:p=1..8,寻找 a.data[ p].j==col 寻找
2.求解步骤分析:p=1..8, q的值 求解步骤分析: 的值=7 求解步骤分析 的值
注意: 注意:
为了保存矩阵的行数、 为了保存矩阵的行数、列 数和非零元素个数, 数和非零元素个数,还需 增设三个量: 增设三个量:mu nu tu
mu=6 nu=7 tu=8
3.三元组线性表的数据类型描述 3.三元组线性表的数据类型描述
#define MAXSIZE 12500 typedef struc{ int ElemType }Triple; typedef struc{ Triple data [MAXSIZE+1]; //三元组表,data[0]不用 三元组表, 三元组表 不用 int mu , nu , tu ; }TSMatrix TSMatrix M ; //矩阵的行数、列数、非0元素个数 矩阵的行数、列数、 矩阵的行数 元素个数 //sparseness(稀疏 稀疏) 稀疏 i, j; e; //非零元素个数的最大值 非零元素个数的最大值
世界那么世界那么大大我们去看我们去看看看世界那么世界那么大大我们去看我们去看看看世界那么世界那么大大我们去看我们去看看看世界那么世界那么大大我们去看我们去看看看世界那么世界那么大大我们去看我们去看看看世界那么世界那么大大我们去看我们去看看看世界那么世界那么大大我们去看我们去看看看sparsematrix例如
求解
b .data 4 b .data 5 b .data 6 b .data 7 b .data 8
数据结构-稀疏矩阵的三元组表存储方法

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;
c语言以三元顺序表表示稀疏矩阵

C语言以三元顺序表表示稀疏矩阵1. 引言稀疏矩阵是指大部分元素为零的矩阵,通常在实际应用中占据大量存储空间。
为了高效处理稀疏矩阵,我们通常会采用三元组顺序表的方式进行表示。
本文将探讨如何使用C语言以三元顺序表表示稀疏矩阵,深入理解其原理和实现方法。
2. 稀疏矩阵的表示方法在C语言中,我们可以使用三元组顺序表来表示稀疏矩阵。
三元组顺序表包括三个部分:行号、列号和元素值。
通过这种方式,我们可以有效地压缩稀疏矩阵,节省存储空间,并且方便进行相关的运算。
3. 三元顺序表的数据结构在C语言中,我们可以使用结构体来定义三元顺序表的数据结构。
具体而言,我们可以定义一个包含行号、列号和元素值的结构体,然后通过数组来存储这些结构体,从而表示整个稀疏矩阵。
4. 如何实现C语言表示稀疏矩阵在C语言中,我们可以通过以下步骤来实现稀疏矩阵的表示:1. 定义一个结构体来存储稀疏矩阵的三元组信息。
2. 创建一个数组,用来存储这些结构体,从而表示整个稀疏矩阵。
3. 编写相关的函数,实现稀疏矩阵的压缩、展开以及相关的运算操作。
5. 样例代码下面是一段简单的C语言代码,用来表示一个稀疏矩阵,并进行相关的计算操作:```#include <stdio.h>#define MAXSIZE 12500// 定义三元组结构体typedef struct {int row;int col;int value;} Triple;// 定义稀疏矩阵typedef struct {Triple data[MAXSIZE + 1]; // 0号单元存储矩阵的行数、列数和非零元个数int mu, nu, tu; // 矩阵的行数、列数和非零元个数} TSMatrix;// 主函数int main() {// 在这里编写相关的稀疏矩阵操作return 0;}```6. 总结与展望通过本文的讨论,我们深入了解了C语言以三元顺序表表示稀疏矩阵的原理和实现方法。
数据结构-稀疏矩阵的三元组表存储方法

a .data 3 3 1 -3
b .data 3 2 1 12
a .data 4 3 6 14 求得 b .data 4 2 5 18
a .data 5 a .data 6 a .data 7
4 3 24
5 2 18 无!
6 1 15
b .data 5 b .data 6 b .data 7
31 9 3 4 24 4 6 -7
b .data 2 1 6 15
a .data 3 3 1 -3
b .data 3 2 1 12
a .data 4 3 6 14 求解 b .data 4 2 5 18
a .data 5 4 3 24
b .data 5 3 1 9
a .data 6 5 2 18
b .data 6 3 4 24
a .data 7 6 1 15
a .data 5 4 3 24
b .data 5
a .data 6 5 2 18
b .data 6
a .data 7 6 1 15
b .data 7
a .data 8 6 4 -7
b .data 8
a. mu=6 a. nu=7 a. tu=8 注:p=1:8,寻找 j=col 的a.data[ p]
a .data 2 1 3 9 Col=6 b .data 2 1 6 15
a .data 3 a .data 4
3 1 -3
b .data 3
3 6 14 求得 b .data 4
2 1 12 2 5 18
a .data 5 4 3 24
b .data 5 3 1 9
a .data 6 5 2 18
2.求解步骤分析:p=1:8, q的值=7
三元组法存储稀疏矩阵

三元组法存储稀疏矩阵
稀疏矩阵是指其中大部分元素都为0的矩阵。
在计算机科学中,稀疏矩阵可以使用三元组法进行存储,以节省内存空间。
三元组法是指将稀疏矩阵中非零元素的行、列和值依次存储在一个三元组中。
具体来说,对于一个m行n列的稀疏矩阵A,可以使用一个大小为k*3的三元组T来存储。
其中,k是非零元素的个数。
三元组T中的每一行即可表示一个非零元素的位置和值。
例如,对于如下的3*3稀疏矩阵:
| 0 0 0|
| 0 5 0|
| 0 0 0|
其三元组表示如下:
| 2 2 5|
其中,第一列表示非零元素在第2行,第二列表示非零元素在第2列,第三列表示非零元素的值为5。
三元组法的优点在于节省了内存空间,并且存储和访问操作较为高效。
但是,对于密集矩阵来说,使用三元组法存储反而会更加浪费空间。
关于如何将稀疏矩阵转换为三元组,可以采用行逐一法或列逐一法。
对于行逐一法,可以先确定每一行非零元素的个数,然后按照行的顺序依次存储对应的三元组。
对于列逐一法,可以先确定每一列非零元素的个数,然后按照列的顺序依次存储对应的三元组。
总之,三元组法是一种方便高效的稀疏矩阵存储方式。
在实际应用中,可以根据具体情况选择是否采用该方法。
存储稀疏矩阵

存储稀疏矩阵稀疏矩阵是一种特殊的矩阵,它的大部分元素都是0。
在实际应用中,很多矩阵都具有稀疏性质,即只有少数非零元素。
如果对这些矩阵进行普通的存储,会占用大量的存储空间,而且对矩阵的运算和处理也会变得非常低效。
为了解决这个问题,人们发展出了一种专门用于存储稀疏矩阵的方法,即稀疏矩阵存储。
稀疏矩阵存储的核心思想是只存储矩阵中非零元素的值以及它们的位置信息,而对于零元素则不进行存储。
这种存储方式可以大大节省存储空间,提高计算效率。
下面我们将介绍两种常用的稀疏矩阵存储方法:压缩稀疏矩阵存储和链表稀疏矩阵存储。
1. 压缩稀疏矩阵存储压缩稀疏矩阵存储是一种基于数组的存储方法。
它将稀疏矩阵转换为一个三元组表,其中每个非零元素都由三个值组成:行号、列号和元素值。
通过这种方式,我们可以只存储非零元素的信息,从而减少存储空间的占用。
同时,由于元素的位置信息也被存储下来,我们可以方便地进行稀疏矩阵的运算和处理。
2. 链表稀疏矩阵存储链表稀疏矩阵存储是一种基于链表的存储方法。
它将稀疏矩阵转换为一个链表,其中每个非零元素都被存储为一个节点,节点包含了行号、列号和元素值。
通过链表的方式,我们可以动态地添加和删除节点,而不需要预先分配存储空间。
这种存储方法在处理稀疏矩阵时非常灵活,尤其适用于那些元素数量不确定的情况。
除了上述两种常用的存储方法外,还有一些其他的稀疏矩阵存储方法,如哈希表存储和位图存储。
这些方法都有各自的特点和适用范围,可以根据实际情况选择合适的存储方法。
稀疏矩阵存储在很多领域都有广泛的应用。
比如,在图像处理中,很多图像都是稀疏的,只有少数像素点是非零的。
通过稀疏矩阵存储,我们可以有效地表示和处理这些图像,从而实现高效的图像处理算法。
另外,在网络分析和推荐系统中,稀疏矩阵存储也被广泛应用。
通过存储用户与物品之间的关系矩阵,我们可以进行用户推荐和相似度计算等任务。
总结起来,稀疏矩阵存储是一种高效地表示和处理稀疏矩阵的方法。
稀疏矩阵的三元组顺序表存储表示

附录1:算法与数据结构课程设计任务书专业班级学号姓名一、设计题目:稀疏矩阵的三元组顺序表存储表示二、基本要求能区分加法、减法、乘法和转置;能处理任意输入的典型数据和进行出错数据处理(例如乘法,当第一个矩阵的列数不等于第二个矩阵的行数时);必须采用三元组作存储结构,不能采用数组等形式;输出要求用矩阵的形式输出(即习题集136页的形式),当第一个矩阵的行数不等于第二个矩阵的行数时,注意如第三个乘法的形式输出三、设计任务设计一个稀疏矩阵的三元组顺序表存储表示四、设计时间2010 年 12 月 19 日至 2011 年 12 月 25 日指导教师:教研室主任:附录2:郑州科技学院算法与数据结构课程设计题目 _稀疏矩阵的三元组顺序表存储表示___学生姓名专业班级学号所在系指导教师完成时间 2011 年12 月 25 日目■■录一、课程设计教学目的及基本要求 (4)二、课程设计内容及安排 (4)1)【概要设计】1抽象数据类型的功能规格明 (4)2详细设计 (5)3.主程序模块与各子程序模块间的调用关系: (5)程序代码 (5)运行与测试 (13)总结与思考 (39)致谢 (39)参考文献 (39)一、课程设计教学目的及基本要求1.了解并掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力;2.初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能;3.提高综合运用所学的理论知识和方法独立分析和解决问题的能力;4.训练用系统的观点和软件开发一般规范进行软件开发,培养软件工作者所应具备的科学的工作方法和作风。
5.设计的题目要求达到一定工作量(300行以上代码),并具有一定的深度和难度。
6. 编写出课程设计说明书,说明书不少于10页(代码不算)。
二、课程设计内容及安排1)【概要设计】1.抽象数据类型的功能规格说明:ADT SparseMatrix{数据对象:D = {aij|i=1,2,…,m;j=1,2,…n;aij∈ElemSet,m和n分别称为矩阵的行数于列数}数据关系:R={Row,Col}Row = {<aij,aij+1>|1<=i<=m,1<=j<=n-1}Col = {<aij,ai+1j>|1<=i<=m-1,1<=j<=n}基本操作:CreatSMatrix(&T)操作结果:创建稀疏矩阵T。
数据结构智慧树知到答案章节测试2023年上海电力大学

第一章测试1.数据结构中,与所使用的计算机无关的是数据的( ) 结构。
A:存储B:逻辑C:物理D:物理和存储答案:B2.从逻辑上可以把数据结构分为()两大类。
A:顺序结构、链式结构B:线性结构、非线性结构C:初等结构、构造型结构D:动态结构、静态结构答案:B3.算法分析的目的是()A:分析算法的效率以求改进B:找出数据结构的合理性C:分析算法的易懂性和文档性D:研究算法中的输入和输出的关系答案:A4.一个”好”的算法应达到的目标有( )。
A:高时间效率和低存储率B:正确性C:可读性D:健壮性答案:ABCD5.健壮的算法不会因非法的输入数据而出现莫名其妙的状态。
A:错B:对答案:B6.数据的逻辑结构和数据的存储结构是相同的。
A:错B:对答案:A7.算法的实现依赖于数据的逻辑结构。
A:错B:对答案:A8.算法是对解题方法和步骤的描述。
A:对B:错答案:A9.链式存储结构所占存储空间()。
A:分两部分,一部分存放结点的值,另一个部分存放表示结点间关系的地址。
B:只有一部分,存储表示结点间关系的地址。
C:只有一部分,存放结点的值。
D:分两部分,一部分存放结点的值,另一部分存放结点所占存储单元值。
答案:A10.下列时间复杂度中最坏的是()。
A:O( logn)B:O(n2)C:O(n)D:O(1)答案:B第二章测试1.在n个结点的顺序表中,算法的时间复杂度是O(1)的操作是:A:将n个结点从小到大排序B:访问第i个结点(1≤i≤n)和求第i个结点的直接前驱(2≤i≤n)C:在第i个结点后插入一个新结点(1≤i≤n)D:删除第i个结点(1≤i≤n)答案:B2.链式存储结构的最大优点是A:存储密度高B:便于进行插入和删除操作C:便于随机存取D:无需预分配空间答案:B3.假设在顺序表{a0,a1,……,an-1}中,每一个数据元素所占的存储单元的数目为4,且第0个数据元素的存储地址为100,则第7个数据元素的存储地址是A:106B:128C:124D:107答案:B4.在一个单链表中的p和q两个结点之间插入一个新结点,假设新结点为s,则修改链的java语句序列是A:s.next=p;p.next=q;B:p.next=q;q.next=s;C:s.next=q;p.next=s;D:q.next=p;p.next=s;答案:C5.顺序存储方式的优点是存储密度大,且插入、删除运算效率高A:错B:对答案:A6.在单链表中,增加一个头结点的目的是为了A:方便运算的实现B:使单链表至少有一个结点C:标识表结点中首结点的位置D:说明单链表是线性表的链式存储答案:A7.一维数组第一个元素的存储地址是100,每个元素的长度为2,则第5个元素的地址是A:108B:110C:120D:100答案:A8.链表的删除算法很简单,因为当删除链中某个结点后,计算机会自动地将后续的各个单元向前移动A:错B:对答案:A9.链表的每个结点中都恰好包含一个指针A:对B:错答案:B10.顺序存储方式只能用于存储线性结构A:对B:错答案:B第三章测试1.若将整数1、2、3、4依次进栈,则不可能得到的出栈序列是A:1234B:4321C:1324D:1423答案:D2.在顺序栈中,若栈顶指针top指向栈顶元素的下一个存储单元,且顺序栈的最大容量是maxSize,则顺序栈的判空条件是A:top==maxSize-1B:top==-1C:top==maxSizeD:top==0答案:D3.在循环顺序队列中,假设以少用一个存储单元的方法来区分队列判满和判空的条件,front和rear分别为队首和队尾指针,front指向队首元素,rear 指向队尾元素的下一个存储单元,队列的最大存储容量为maxSize,则队列的判满条件是A:front==rear+1B:front==(rear+1)% maxSizeC:front!=rearD:front==rear答案:B4.在链栈中,进行出栈操作时A:需要判断栈是否为空B:无需对栈作任何差别C:需要判断栈是否满D:需要判断栈元素的类型答案:A5.栈和队列是一种非线性数据结构A:错B:对答案:A6.在循环顺序队列中,假设以少用一个存储单元的方法来区分队列判满和判空的条件,front和rear分别为队首和队尾指针,它们分别指向队首元素和队尾元素的下一个存储单元,队列的最大存储容量为maxSize,则队列的判空条件是A:front==(rear+1)% maxSizeB:front==rear+1C:front!=rearD:front==rear答案:D7.循环顺序队列是将顺序队列的存储区域看成是一个首尾相连的环,首尾相连的状态是通过数学上的哪种运算实现的?A:求余B:求和C:减运算D:除运算答案:A8.设数组Data[0..m]作为循环队列SQ的存储空间,front为队头指针,rear为队尾指针,则执行出队操作的语句为A:front=(front+1)% mB:front=front+1C:front=(front+1)%(m+1)D:rear=(rear+1)%m答案:C9.假定利用数组a[n]顺序存储一个栈,用top表示栈顶指针,top==-1表示栈空,并已知栈未满,当元素x进栈时所执行的操作为A:a[top–]=xB:a[++top]=xC:a[–top]=xD:a[top++]=x答案:B10.在不带表头结点的链栈中,若栈顶指针top直接指向栈顶元素,则将一个新结点p入栈时修改链的两条对应语句为A:top=p;p.next=top;B:p.next=top;top=p;C:p=top;top.next=p.next;D:top.next=p;p=top;答案:B第四章测试1.下面关于串的叙述中,哪一个是不正确的?( )A:串既可以采用顺序存储,也可以采用链式存储B:空串是由空格构成的串C:模式匹配是串的一种重要运算D:串是字符的有限序列答案:B2.串的长度是指( )A:串中包含的不同字符个数B:串中除空格以外的字符个数C:串中包含的不同字母个数D:串中包含的字符个数答案:D3.设有两个串p和q,其中q是p的子串,求q在p中首次出现的位置的算法称为( )A:联接B:求子串C:求串长D:模式匹配答案:D4.设主串的长度为n,模式串的长度为m,则串匹配的KMP算法时间复杂度是( )A:O(n×m)B:O(n)C:O(m)D:O(n + m)答案:D5.串也是一种线性表,只不过( )A:数据元素均为字符B:数据元素是子串C:表长受到限制D:数据元素数据类型不受限制答案:A6.一个串的任意连续字符组成的子序列称为串的子串,该串称为主串。
稀疏矩阵 存储方法

稀疏矩阵存储方法
存储稀疏矩阵的一种常见方法是使用三元组表示法(Triplet representation)。
三元组表示法包含三个数组(或链表),分别存储非零元素的行下标、列下标和对应的值。
具体来说,假设稀疏矩阵的大小为m行n列,其中包含k个非零元素,那么三元组表示法的结构如下:
1. 一个长度为k的数组row_index,用于存储非零元素的行下标。
2. 一个长度为k的数组col_index,用于存储非零元素的列下标。
3. 一个长度为k的数组value,用于存储非零元素的值。
这样,对于稀疏矩阵中的每一个非零元素,可以通过三个数组的对应位置来获取其行下标、列下标和值。
使用三元组表示法的优点是可以节省存储空间,因为只需要存储非零元素的信息,而对于零元素可以省略。
另外,由于三元组表示法是按照元素出现的顺序存储的,可以方便地遍历稀疏矩阵的非零元素。
然而,三元组表示法也存在一些限制,比如在插入或删除元素时可能需要移动大量的元素位置,效率较低。
因此,在实际应用中,还存在其他更加高效的存储方法,比如压缩稀疏行(Compressed Sparse Row,CSR)和压缩稀疏列
(Compressed Sparse Column,CSC)等。
稀疏矩阵csr存储规则

稀疏矩阵csr存储规则
稀疏矩阵CSR存储规则。
稀疏矩阵是指大部分元素为零的矩阵,对于这种矩阵,传统的
存储方式会造成大量的存储空间浪费。
因此,稀疏矩阵CSR (Compressed Sparse Row)存储规则应运而生。
在CSR存储规则中,矩阵被分为三个数组来存储,值数组(values),列索引数组(col_index)和行偏移数组(row_ptr)。
这种存储方式可以大大减少存储空间的浪费,提高了矩阵的存储效率。
具体来说,值数组存储矩阵中非零元素的值,列索引数组存储
每个非零元素对应的列索引,而行偏移数组存储每一行的第一个非
零元素在值数组中的索引位置。
这样一来,我们可以通过行偏移数
组来确定每一行非零元素的位置,通过列索引数组找到对应的列索引,然后在值数组中找到具体的值。
通过CSR存储规则,我们可以高效地存储和检索稀疏矩阵的数据,减少存储空间的浪费,提高计算效率。
因此,在处理大规模稀
疏矩阵时,CSR存储规则是一种非常有效的存储方式。
总而言之,稀疏矩阵CSR存储规则通过将矩阵分解为值数组、列索引数组和行偏移数组,实现了对稀疏矩阵高效存储和检索的目的,为处理大规模稀疏矩阵提供了重要的技术支持。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
求解
b .data 4 b .data 5 b .data 6 b .data 7 b .data 8
a. mu=6 a. nu=7 a. tu=8
注:p=1..8,寻找 a.data[ p].j==col 寻找
2.求解步骤分析:p=1..8, q的值 求解步骤分析: 的值=7 求解步骤分析 的值
a . data p a .data 1 a .data 2 a .data 3 a .data 4 a .data 5 a .data 6 a .data 7 a .data 8 i 1 1 3 3 4 5 6 6 j 2 3 1 6 3 2 1 4 e 12 9 -3 14 24 18 15 -7 Col=3 b . data q b .data 1 b .data 2 b .data 3 i 1 1 2 2 3 3 j 3 6 1 5 1 4 e -3 15 12 18 9 24
注意: 注意:
引用i 引用 , j ,e 时的格 式应为: 式应为: a . data[p] . i a . data[p] . j a . data[p] . e 例如 x=a . data[6] . j 则 x=2
a. mu=6 a. nu=7 a. tu=8
三、实现矩阵的运算:矩阵转置 实现矩阵的运算 矩阵转置
a . data p a .data 1 a .data 2 a .data 3 a .data 4 a .data 5 a .data 6 a .data 7 a .data 8 i 1 1 3 3 4 5 6 6 j 2 3 1 6 3 2 1 4 e 12 9 -3 14 24 18 15 -7 Col=4 b . data q b .data 1 b .data 2 b .data 3 i 1 1 2 2 3 3 4 j 3 6 1 5 1 4 6 e -3 15 12 18 9 24 -7
求解
b .data 4 b .data 5 b .data 6 b .data 7 b .data 8
a. mu=6 a. nu=7 a. tu=8
注:p=1..8,寻找 a.data[ p].j==col 寻找
2.求解步骤分析:p=1..8, q的值 求解步骤分析: 的值=5,6 求解步骤分析 的值
求解
b .data 4 b .data 5
无!
b .data 6 b .data 7 b .data 8
a. mu=6 a. nu=7 a. tu=8
注:p=1..8,寻找 a.data[ p].j==col 寻找
2.求解步骤分析:p=1..8, q的值 求解步骤分析: 的值=8 求解步骤分析 的值
求解
b .data 4 b .data 5 b .data 6 b .data 7 b .data 8
a. mu=6 a. nu=7 a. tu=8
注:p=1..8,寻找 a.data[ p].j==col 寻找
2.求解步骤分析:p=1..8, q的值 求解步骤分析: 的值=3,4 求解步骤分析 的值
的形式如下: 用变量 a 存放矩阵 M 的形式如下:
a . data p a .data 1 a .data 2 a .data 3 a .data 4 a .data 5 a .data 6 a .data 7 a .data 8 i 1 1 3 3 4 5 6 6 j 2 3 1 6 3 2 1 4 e 12 9 -3 14 24 18 15 -7
求解
b .data 4 b .data 5 b .data 6 b .data 7 b .data 8
a. mu=6 a. nu=7 a. tu=8
b. mu=7 b. nu=6 b. tu=8
2.求解步骤分析:p=1..8, q的值 求解步骤分析: 的值=1,2 求解步骤分析 的值
a . data p a .data 1 a .data 2 a .data 3 a .data 4 a .data 5 a .data 6 a .data 7 a .data 8 i 1 1 3 3 4 5 6 6 j 2 3 1 6 3 2 1 4 e 12 9 -3 14 24 18 15 -7 Col=1 b . data q b .data 1 b .data 2 b .data 3 i 1 1 j e 3 -3 6 15
如果矩阵M中的大多数元素均 如果矩阵 中的大多数元素均 为零元素,则称矩阵M为稀疏矩阵 为稀疏矩阵。 为零元素,则称矩阵 为稀疏矩阵。
例如: 例如:
0 0 -3 0 0 15 12 9 0 0 0 0 0 0 0 0 24 0 18 0 0 0 0 -7 0 0 0 0 0 0 0 0 14 0 0 0 0 0 0 0 0 0
5.3.2 稀疏矩阵的压缩存储 ———三元组表 三元组表
一、什么是稀疏矩阵(sparse matrix) 什么是稀疏矩阵
如果矩阵M中的大多数元素均 如果矩阵 中的大多数元素均 为零元素,则称矩阵M为稀疏矩阵 为稀疏矩阵。 为零元素,则称矩阵 为稀疏矩阵。
一、什么是稀疏矩阵(sparse matrix) 什么是稀疏矩阵
注意: 注意:
为了保存矩阵的行数、 为了保存矩阵的行数、列 数和非零元素个数, 数和非零元素个数,还需 增设三个量: 增设三个量:mu nu tu
mu=6 nu=7 tu=8
3.三元组线性表的数据类型描述 3.三元组线性表的数据类型描述
#define MAXSIZE 12500 typedef struc{ int ElemType }Triple; typedef struc{ Triple data [MAXSIZE+1]; //三元组表,data[0]不用 三元组表, 三元组表 不用 int mu , nu , tu ; }TSMatrix TSMatrix M ; //矩阵的行数、列数、非0元素个数 矩阵的行数、列数、 矩阵的行数 元素个数 //sparseness(稀疏 稀疏) 稀疏 i, j; e; //非零元素个数的最大值 非零元素个数的最大值
1.实例 求矩阵 的转置矩阵 实例:求矩阵 的转置矩阵N: 实例 求矩阵M的转置矩阵
三、实现矩阵的运算:矩阵转置 实现矩阵的运算 矩阵转置
1.实例 求矩阵 的转置矩阵 实例:求矩阵 的转置矩阵N: 实例 求矩阵M的转置矩阵
0 0 -3 0 0 15 12 9 0 0 0 0 0 0 0 0 24 0 18 0 0 0 0 -7 0 0 0 0 0 0 0 0 14 0 0 0 0 0 0 0 0 0 0 12 9 N= 0 0 0 0 0 0 0 0 0 0 0 -3 0 0 0 0 18 0 24 0 0 0 0 0 0 0 14 0 0 0 0 0 15 0 0 -7 0 0 0
3 14
a. mu=6 a. nu=7 a. tu=8
注:p=1..8,寻找 a.data[ p].j==col 寻找
2.求解步骤分析:p=1..8, q的值 求解步骤分析: 的值=8 求解步骤分析 的值
a . data p a .data 1 a .data 2 a .data 3 a 4 a .data 5 a .data 6 a .data 7 a .data 8 i 1 1 3 3 4 5 6 6 j 2 3 1 6 3 2 1 4 e 12 9 -3 14 24 18 15 -7 Col=7 b . data q b .data 1 b .data 2 b .data 3 i 1 1 2 2 3 3 4 6 j 3 6 1 5 1 4 6 3 e -3 15 12 18 9 24 -7 14
M=
二、三元组线性表存储结构
1.中心思想:仅存储矩阵中的非零元素 中心思想: 中心思想 用一个三元组( 用一个三元组(tupel3)存放矩阵中的 ) 一个非零元素的行号、列号及该 一个非零元素的行号、列号及该非零元素 的值。 一个三元组的形式为:( :(i 的值。 一个三元组的形式为:( , j, e) ) 一般情况下, 一般情况下,一个稀疏矩阵中有若干个 非零元素,所以要用一个“三元组线性表” 非零元素,所以要用一个“三元组线性表” 来存放一个稀疏矩阵。 来存放一个稀疏矩阵。
求解
b .data 4 b .data 5 b .data 6 b .data 7 b .data 8
a. mu=6 a. nu=7 a. tu=8
注:p=1..8,寻找 a.data[ p].j==col 寻找
2.求解步骤分析:p=1..8, q的值 求解步骤分析: 的值=7 求解步骤分析 的值
a . data p a .data 1 a .data 2 a .data 3 a .data 4 a .data 5 a .data 6 a .data 7 a .data 8 i 1 1 3 3 4 5 6 6 j 2 3 1 6 3 2 1 4 e 12 9 Col=6 -3 14 求解 24 18 15 -7 b . data q b .data 1 b .data 2 b .data 3 b .data 4 b .data 5 b .data 6 b .data 7 b .data 8 i 1 1 2 2 3 3 4 6 j 3 6 1 5 1 4 6 e -3 15 12 18 9 24 -7
M=
求解
注意:用变量 和 分别存放矩阵 注意:用变量a和 b分别存放矩阵 M和N (TSMatrix a,b),既要从已 和 既要从已 知变量a来求得变量 的值。 来求得变量b的值 知变量 来求得变量 的值。
也既要完成如下求解工作: 也既要完成如下求解工作:
a . data p a .data 1 a .data 2 a .data 3 a .data 4 a .data 5 a .data 6 a .data 7 a .data 8 i 1 1 3 3 4 5 6 6 j 2 3 1 6 3 2 1 4 e 12 9 -3 14 24 18 15 -7 b . data q b .data 1 b .data 2 b .data 3 i 1 1 2 2 3 3 4 6 j 3 6 1 5 1 4 6 3 e -3 15 12 18 9 24 -7 14