当前位置:首页 » 服务存储 » 三元组存储的特点
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

三元组存储的特点

发布时间: 2022-02-12 00:58:58

‘壹’ 抽象数据类型三元组的定义什么意思

三元组指形如((x,y),z)的集合(这就是说,三元组是这样的偶,其第一个射影亦是一个偶),常简记为(x,y,z)。

三元组为计算机专业的一门公共基础课程——数据结构里的概念。主要用来存储稀疏矩阵的一种压缩方式,也叫三元组表。假设以顺序存储结构来表示三元组表(triple table),则得到稀疏矩阵的一种压缩存储方式,即三元组顺序表,简称三元组表。



(1)三元组存储的特点扩展阅读

抽象数据类型的特征主要体现在以下几个方面:

1、数据抽象。用ADT描述程序处理的实体时,强调的是其本质的特征、其所能完成的功能以及它和外部用户的接口(即外界使用它的方法)。

2、数据封装。将实体的外部特性和其内部实现细节分离,并且对外部用户隐藏其内部实现细节,它包含两层含义:

将数据和其行为结合在一起,形成一个不可分割的独立单位;信息隐藏,即尽可能隐藏数据内部细节,只留有限的对外接口形成一个边界,与外部发生联系。封装的原则使得软件错误能够局部化,大大降低排错的难度,便于软件的维护。

3、继承性。数据封装使得一个类型可以拥有一般类型的数据和行为,即对一般类型的继承。若特殊类型从多个一般类型中继承相关的数据和行为,则为多继承。

4、多态性。多态性指在一般类型中定义的数据或行为被特殊类型继承后,具有不同的数据类型或呈现出不同的行为。例如,“苹果”是“水果”的子类,它可以有“水果”的一般“吃”法,但其本身还可以有别的多种“吃法”。

‘贰’ 稀疏矩阵的三元组顺序表存储结构是随机存储结构吗为什么

不是随机存储 写成三元租顺序表无法使用如A3*4这种方式查找钙元素

‘叁’ 三元组存储稀疏矩阵的好处是神马呢急求!!

三元组仅存储矩阵中不为零的元素,节省了存储空间。
缺点是增加运算的复杂性,尤其是随机存取矩阵元素时。

‘肆’ 急!三元组顺序表的存储结构形成

/*~~~~稀疏矩阵的三元组顺序表存储结构类型定义及部分常见操作算法(smatrix.c)~~~~*/
#ifndef __SPARSEMATRIX__
#define __SPARSEMATRIX__

#ifndef COMMONELEM
#define COMMONELEM 0 /*公共元的值*/
#endif

#include <stdlib.h>
/*三元组顺序表存储空间长度的最小值*/
#define MATRIXMINSIZE 10
/*三元组顺序表存储结构类型定义*/
typedef struct
{
int row; /*行号*/
int col; /*列号*/
MatrixDT value; /*特殊元的值*/
}ThrElem; /*三元组元素类型*/

typedef struct
{
ThrElem *base; /*三元组表的基地址*/
int listsize; /*三元组表的存储空间尺寸*/
int len; /*三元组表的长度,即矩阵中特殊元的个数*/
int rows,cols; /*矩阵的行数、列数*/
}SMatrix;

/*矩阵初始化*/
void MatrixInitialize(SMatrix *pM, int size, int rows, int cols)
{
if(size<MATRIXMINSIZE)
size=MATRIXMINSIZE;
pM->listsize = size;
pM->base=(ThrElem *)malloc(pM->listsize*sizeof(ThrElem));
if(!pM->base)
exit(EXIT_FAILURE);
pM->rows=rows;
pM->cols=cols;
pM->len=0;
}

/*输出矩阵*/
void MatrixPrint(SMatrix M, void (*cout)(MatrixDT))
{
int i,j,k;
for(k=0,i=0; i<M.rows; i++)
{
for(j=0; j<M.cols; j++)
if(k<M.len && i==M.base[k].row && j==M.base[k].col)
(*cout)(M.base[k++].value);/*输出特殊元*/
else
(*cout)(COMMONELEM); /*输出公共元*/
printf("\n");
}
}

/*取矩阵元素*/
BOOL GetElem(SMatrix M, MatrixDT *pd, int i, int j)
{
int k, addr;
BOOL flg=TRUE;
if(i<0 || i>M.rows-1 || j<0 || j>M.cols-1)
flg=FALSE;/*访问越界*/
else
{
*pd = COMMONELEM;
/*
由于三元组顺序表中特殊元是按"以行优先的顺序并保持同一行中列号从小到大的
规律"保存的,故,可以把矩阵中每个特殊元的二元(行号和列号)逻辑地址转换
成递增有序的一元伪地址addr=行号*列数+列号;
本算法采用的是最简单的顺序查找方法。
由于关键字序列是递增有序的,所以也可以使用折半查找(详见第10章)等算法,
那样效率会更高。
*/
addr=i*M.cols+j;
for(k=0; k<M.len && M.base[k].row*M.cols +M.base[k].col <addr; k++)
;
if(k<M.len && i==M.base[k].row && j==M.base[k].col)
/*M[i][j]是特殊元*/
*pd = M.base[k].value;
}
return flg;
}

/*写矩阵元素*/
BOOL PutElem(SMatrix *pM, MatrixDT d, int i, int j,
BOOL (*equal)(MatrixDT,MatrixDT))
{
int k,m,addr;
BOOL flg=TRUE;
if(i<0 || i>pM->rows-1 || j<0 || j>pM->cols-1 || pM->len >=pM->listsize)
flg=FALSE;/*访问越界*/
else
{
addr=i*pM->cols +j;
/*扫描到i行中j列元素应在的位置*/
for(k=0;k<pM->len &&
pM->base[k].row* pM->cols +pM->base[k].col<addr; k++)
;
if(k<pM->len && i==pM->base[k].row && j==pM->base[k].col)
{
/*原来是特殊元*/
if((*equal)(d,COMMONELEM))
{
/*第1种情况:原来是特殊元,写入的是公共元值。从表中删除元素*/
for(m=k+1; m<pM->len; m++)
pM->base[m-1]=pM->base[m];
pM->len--;
}
else
/*第2种情况:原来是特殊元,写入的是特殊元值,更改元素值*/
pM->base[k].value=d;
}
else /*原来是公共元*/
{
if(!(*equal)(d,COMMONELEM))
{
/*第3种情况:原来是公共元,写入的是特殊元值。在表中k位置插入新元素*/
for(m=pM->len-1; m>=k; m--)
pM->base[m+1]=pM->base[m];
pM->base[k].row=i;
pM->base[k].col=j;
pM->base[k].value =d;
pM->len++;
}
else
/*第4种情况:原来是公共元,写入的是公共元值。空操作*/
;
}
}
return flg;
}

/*拷贝矩阵*/
void MatrixCopy(SMatrix* pM, SMatrix M)
{
int i;
pM->listsize = M.listsize;
pM->rows = M.rows;
pM->cols = M.cols;
pM->len = M.len;
/*申请存储空间*/
pM->base=(ThrElem *)malloc(pM->listsize*sizeof(ThrElem));
if(!pM->base)
exit(EXIT_FAILURE);

for(i=0; i<pM->len; i++)
pM->base[i]=M.base[i];/*复制数组中单元的值*/
}

/*矩阵加法*/
BOOL MatrixAdd(SMatrix* pM, SMatrix M, SMatrix N,
MatrixDT (*add)(MatrixDT,MatrixDT),BOOL (*equal)(MatrixDT,MatrixDT))
{
int i,j,k,addrM,addrN;
/*pM所指矩阵有可能是矩阵M或矩阵N,故先用base缓存结果,最后再给pM->base*/
ThrElem *base;
MatrixDT d;
BOOL flg=TRUE;
if(M.rows !=N.rows || M.cols!=N.cols)
flg=FALSE;
else
{
base=(ThrElem*)malloc((M.len + N.len)*sizeof(ThrElem));
if(!base)
exit(EXIT_FAILURE);
/*i、j和k分别指示M.base、N.base和临时数据区base的首位置*/
i=j=k=0;
while(i<M.len && j<N.len)
{
/*计算矩阵M和矩阵N递增有序的一元伪地址addrM和addrN*/
addrM=M.base[i].row*M.cols + M.base[i].col;
addrN=N.base[j].row*N.cols + N.base[j].col;
if(addrM==addrN)/*两个矩阵中存在位置相同的特殊元*/
{
/*d是两个位置相同的特殊元相加之和*/
d=(*add)(M.base[i].value , N.base[j].value);
if(!(*equal)(d, COMMONELEM))
{
/*d是特殊元,把(i,j,d)追加到base数组*/
base[k].row =M.base[i].row;
base[k].col =M.base[i].col;
base[k++].value =d;
}
i++;
j++;
}
else if(addrM < addrN) /*矩阵M中当前特殊元应先追加到base数组*/
{
base[k]=M.base[i++];
base[k++].value=(*add)(base[k].value, COMMONELEM);
}
else /*矩阵N中当前特殊元应先追加到base数组*/
{
base[k++]=N.base[j++];
base[k++].value=(*add)(base[k].value, COMMONELEM);
}
}
/*将矩阵M或矩阵N中剩余的特殊元追加到base数组*/
for(; i<M.len; i++)
{
base[k]=M.base[i++];
base[k++].value=(*add)(base[k].value, COMMONELEM);
}
for(; j<N.len; j++)
{
base[k]=N.base[j++];
base[k++].value=(*add)(base[k].value, COMMONELEM);
}
if(k>pM->listsize)
exit(EXIT_FAILURE);
/*复制结果数据到pM->base区*/
for(i=0; i<k; i++)
pM->base[i]=base[i];
free(base);
pM->rows=M.rows;
pM->cols=M.cols;
pM->len =k;
}
return flg;
}

/*矩阵转置*/
void MatrixTranspose(SMatrix *pM, SMatrix M)
{
int col,i,j;
ThrElem *base;
/*
本函数允许如下调用方式:
MatrixTranspose(&m, m);
所以要额外申请存储空间base
*/
base=(ThrElem*)malloc(M.listsize*sizeof(ThrElem));
if(!base)
exit(EXIT_FAILURE);
for(i=0,col=0; col<M.cols; col++) /*col是转置后矩阵的行号*/
for(j=0; j<M.len; j++)
if(M.base[j].col == col)
{
/*特殊元行列对换后写入新表空间*/
base[i].row = M.base[j].col;
base[i].col = M.base[j].row;
base[i].value = M.base[j].value;
i++;
}
pM->listsize =M.listsize;
pM->len =M.len;
pM->rows=M.cols;
pM->cols=M.rows;
free(pM->base);
pM->base=base;
}

/*销毁矩阵*/
void MatrixDestroy(SMatrix M)
{
free(M.base);
}

#endif
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

/*
建议性测试用程序
*/
typedef enum {TRUE=1,FALSE=0} BOOL;
typedef int MatrixDT;
#include "smatrix.c"

#define inFORMAT "%d"
#define outFORMAT "%3d"

void printdata(MatrixDT x)
{
printf(outFORMAT,x);
}
MatrixDT add(MatrixDT x, MatrixDT y)
{
return x+y;
}
BOOL equal(MatrixDT x, MatrixDT y)
{
return x==y ? TRUE: FALSE;
}
void main()
{
int i,j,x, y, tlimit;
MatrixDT d;
SMatrix M,N;
BOOL valid=TRUE;
printf("请输入矩阵M的行数、列数及特殊元个数的上限值:\n");
scanf("%d%d%d",&x,&y, &tlimit);
MatrixInitialize(&M,tlimit, x, y);
while(valid)
{
printf("请输入特殊元的行号、列号(行号或列号无效时结束):\n");
scanf("%d%d",&x, &y);
printf("请输入特殊元的值\n");
scanf(inFORMAT, &d);
valid=PutElem(&M,d,x,y,equal);
}
printf("原矩阵=\n");
MatrixPrint(M, printdata);
MatrixTranspose(&M,M);
printf("转置后矩阵=\n");
MatrixPrint(M, printdata);
printf("请输入要读取的单元的行号和列号:\n");
scanf("%d%d",&i,&j);
if(GetElem(M,&d,i,j))
{
printf("M[%d][%d]=",i,j);
printf(outFORMAT, d);
printf("\n");
}
else
printf("Invalid.\n");
MatrixPrint(M, printdata);
printf("Copy M to N.\n");
MatrixCopy(&N,M);
if(MatrixAdd(&M,M,N, add, equal))
{
printf("M+N=\n");
MatrixPrint(M, printdata);
}
MatrixDestroy(M);
}

‘伍’ 稀疏矩阵三元组存储结构的定义及其有关算法的实现

/*我写的一个例子,基本上将稀疏矩阵三元组存储结构的定义和其有关的算法都实现了,你可以借一本关于数据结构c语言实现的书来看一下*/
#include<stdio.h>
#define MAXSIZE 1000//非零元素的个数最多为1000
typedef struct {
int row;
int col;
int e;
}Triple;
typedef struct{
Triple data[MAXSIZE];//非零元素的三元组表
int m;//矩阵的行数
int n;//矩阵的列数
int non_zero_num;//非零元数的个数
}XSMatrix;
XSMatrix XSM_Info_Input(XSMatrix s){
int i;
printf("输入矩阵的行数:");
scanf("%d",&s.m);
printf("输入矩阵的列数:");
scanf("%d",&s.n);
printf("输入矩阵的非零元素的个数:");
scanf("%d",&s.non_zero_num);
for(i=0;i<s.non_zero_num;i++){
printf("输入第%d个非零元数的信息:\n",i+1);
printf("行下标:");
scanf("%d",&s.data[i].row);
printf("列下标:");
scanf("%d",&s.data[i].col);
printf("元素的值");
scanf("%d",&s.data[i].e);
}
return s;
}
void XSM_Info_Output(XSMatrix s){
int i;
printf("\n稀疏矩阵行数和列数:%d\t%d\n",s.m,s.n);
printf("稀疏矩阵三元组表如下:\n");
printf("行下标\t列下标\t值\n");
for(i=0;i<s.non_zero_num;i++){
printf("%d\t%d\t%d\n",s.data[i].row,s.data[i].col,s.data[i].e);
}
}
//列序递增转置法
XSMatrix TransXSM(XSMatrix s){
XSMatrix d;
int i,j,k=0;
d.m=s.n;
d.n=s.m;
d.non_zero_num=s.non_zero_num;
for(i=0;i<s.n;i++){
for(j=0;j<s.non_zero_num;j++){
if(s.data[j].col==i)
{
d.data[k].row=s.data[j].col;
d.data[k].col=s.data[j].row;
d.data[k].e=s.data[j].e;
k++;
}
}
}
return d;
}
main(){
XSMatrix source,dest;
source=XSM_Info_Input(source);
XSM_Info_Output(source);
dest=TransXSM(source);
XSM_Info_Output(dest);
}

‘陆’ 利用三元组存储任意稀疏矩阵时,在什么条件下能节省存储空间 简答题

若一个稀疏矩阵有T个非零元素,则需要T+1行的三元组来表示稀疏矩阵.一般对于M*N的矩阵来说,只要满足3(T+1)<=M*N 这个条件,使用三元组存储可以节省空间.

‘柒’ 数组的三元组存储是对 什么 矩阵的压缩存储

数组的三元组表存储是对稀疏矩阵的压缩存储。

‘捌’ 三元组表示稀疏矩阵是什么

三元组表示稀疏矩阵如下:

从方法上讲,所谓的三元组法表示稀疏矩阵是:将非零元素所在的行、列以及它的值构成一个三元组(i、j、v),然后再按某种规律存储这些三元组,这种方法可以节约存储空间。

对于稀疏矩阵,采用压缩存储方法时,只存储非0元素。必须存储非0元素的行下标值、列下标值、元素值。因此,一个三元组唯一确定稀疏矩阵的一个非零元素。

稀疏矩阵和三元组的特点:

稀疏矩阵的概念是:一个m行n列的矩阵,若它的非零元个数特别少,即可称它为稀疏矩阵。只存储稀疏矩阵的非零元。除了存储非零元的值a以外,还必须记下它的行下标i和列下标j。反之,一个三元组唯一确定矩阵的一个非零元。因此,一个稀疏矩阵可由一个三元组数组和该矩阵的行列数来确定。

‘玖’ 什么是数据结构中的二元组、三元组和五元组

二元组的定义:<K,R>
三元组的定义:<D,F,A>
五元组的定义:<V,O,G,M,S>
V是值的集合,O是操作的集合,G是构成名字的文法,M是存储的集合,S是从G能构成的名字几个到M的映射.

‘拾’ 三元组的存储及转置

#include <iostream>
using namespace std;

int b[100][100]={0};
int c[100][100]={0};
int d[100][100]={0};

struct node
{
int i;
int j;
int e;
};
class jz
{
node a[100];
int p,s,m,n,k,n1,n2;
public:
void datain();
void datacal();
void dataout();
};

void jz::datain()
{

cin>>m>>n1;
cin>>s;
for(p=1;p<=s;p++)
{
cin>>a[p].i>>a[p].j>>a[p].e;
b[a[p].i][a[p].j]=a[p].e;
}

cin>>n2>>k;
cin>>s;
for(p=1;p<=s;p++)
{
cin>>a[p].i>>a[p].j>>a[p].e;
c[a[p].i][a[p].j]=a[p].e;
}
if (n1==n2) n=n1;
else n=-100;
}
void jz::datacal()
{

if(n<0) exit(1);
else
{
for (int s=1;s<=m;s++)
for (p=1;p<=n;p++)
for (int l=1;l<=k;l++)
d[s][l]+=b[s][p]*c[p][l];
}
}
void jz::dataout()
{
// cout<<"**m"<<m<<"**n"<<n<<"**k"<<k<<endl;
if(n<0) cout<<"Error"<<endl;
else
for(int s=1;s<=m;s++)
{
for(int l=1;l<=k;l++)
cout<<d[s][l]<<' ';
cout<<'\n';
}
}
int main()
{
jz t1;
t1.datain();
t1.datacal();
t1.dataout();
return 0;
}