『壹』 抽象數據類型三元組的定義什麼意思
三元組指形如((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;
}