一、数组
一维数组、二维数组(二维数组的行优先和列优先存储)
二、矩阵
- 特殊矩阵:对称矩阵、上(下)三角矩阵、三对角矩阵
- 稀疏矩阵:矩阵中绝大多数元素都为零的矩阵。
- 常用的稀疏矩阵顺序存储方法:三元组表示法和伪地址表示法。
- 稀疏矩阵链式存储方法中常的用两种表示法:邻接表表示法和十字链表表示法。
三、广义表
- 广义表:表元素可以是原子或者广义表的一种线性表的扩展结构。
- 广义表的长度:为表中最上层元素的个数。
- 广义表的深度:为表中括号的最大层数。
- 表头(Head)和表尾(Tail):当广义表非空时,第一个元素为广义表的表头,其余元素组成的表示是广义表的表尾。
广义表例:
- A( ), A是一个空表,长度为0,深度为1 。
- B(d,e), B的元素全是原子,即d和e,长度为2,深度为1。
- C=(b,(c,d)), C有两个元素,分别时原子b和另一个广义表(c,d)长度为2,深度为2。
- D=(B,C), D的元素全是广义表,即B和C,长度为2,深度为3.可见一个广义表的子表可以时其他已经定义的广义表的引用D=(B,C),D的元素全是广义表,即B和C,长度为2,深度为3。可见一个广义表的子表可以时其他已经定义的广义表的引用。
- E=(a,E),E有两个元素,分别是原子和它本身,长度为2,可见一个广义表可以是递归定义的。
四、代码实现
矩阵的转置、相加、相乘操作
//声明一个二维数组
#define m 4
#define n 5
int A[m][n];
//transport matirx 转置矩阵
void trsmat(int A[][maxSize],int B[][maxSize],int m,int n)
{
for(int i=0;i<m;++i)
for(int j=0;j<n;++j)
B[j][i]=A[i][j];
}
//矩阵相加
void addmat(int C[][maxSize],int A[][maxSize],int B[][maxSize],int m,int n)
{
for(int i=0;i<m;++i)
for(int j=0;j<n;++j)
C[i][j]=A[i][j]+B[i][j];
}
//矩阵相乘
void mutmat(int C[][maxSize],intA[][maxSize],int B[][maxSize],int m,int n,int k)
{
for(int i=0;i<m;++i)
for(int j=0;j<k;++j)
{
C[i][j]=0;
for(int h=0;h<n;++h)
C[i][j]+=A[i][h]*B[h][j];
}
}
三元组表示法
//三元组表示法
typedef struct
{
int val; //元素的值
int i,j; //i,j分别为行下标,列下标
}Trimat;
//定义一个含有maxterms个非零元素的稀疏矩阵
Trimat trimat[maxterms+1]; //maxterms是已定义的常量
trimat[k].val;//表示取第k个非零元素的值
trimat[k].i;//表示第k个非零元素在矩阵中的行下标
trimat[k].j;//表示第k个非零元素在矩阵中的列下标
//直接申请数组来表示三元组
int trimat[maxterms+1][3];
//trimat[k][0]表示原矩阵中的元素按行优先顺序的第k个非零元素的值
//trimat[k][1],trimat[k][2]表示第k个非零元素在矩阵中的位置
trimat[0][0];//原矩阵中非零元素个数
trimat[0][1],trimat[0][2];//矩阵行数,列数
//可以看出,trimat是一个maxterms行3列的数组,
//规定第0行的3个元素分别来存储非零元素个数、行数和列数
//给定一个float型稀疏矩阵A,尺寸为m,n,并输出。
void createtrimat(float A[][maxSize],int m,int n,float B[][3])
{
int k=1;
for(int i=0;i<m;++i)
for(int j=0;j<n;++j)
if(A[i][j]!=0)
{
B[k][0]=A[i][j];
B[k][1]=i;
B[k][2]=j;
++k;
}
B[0][0]=k-1;
B[0][1]=m;
B[0][2]=n;
}
//通过三元组打印矩阵
void print (flaot B[][3])
{
int k=1;
for(int i=0;i<B[0][1];++i)
{
for(int j=0;j<B[0][2];++j)
{
if(i==(int)B[k][1]&&j==(int)B[k][2])
{
cout<<B[k][0]<<" "
++k;
}
else
cout<<"0";
}
cout<<endl;
}
}
十字链表表示稀疏矩阵
//十字链表中的两种结点的结构定义
typedef struct OLNode //普通结点
{
int row,col; //行号和列号
struct OLNode *right,*down; //指向右结点和下方结点
float val;
}OLNode;
typedef struct //头结点结构定义
{
OLNode *rhead,*chead; //指向两头结点数组的指针
int m,n,k; //矩阵行数,列数以及非零结点总数
}CrossList;
//给定一个稀松矩阵A,其尺寸为m行,n,非零元素为k个,建立相应十字链表
int createcrossListmat(float A[][maxSize],int m,int n,int k,CrossList &M)
{
if(M.rhead) //rhead 行结点
free(M.rhead);
if(M.chead) //列结点
free(M.chead);
M.m=m;
M.n=n;
M.k=k;
/*申请头结点数组空间*/
if(!(M.rhead=(OLNode*)malloc(sizeof(OLNode)*m)));
return 0;
if(!(M.chead=(OLNode*)malloc(sizeof(OLNOde)*n)));
return 0;
/*头结点数组right和down指针置空*/
for(int i=0;i<m;++i)
{
M.rhead[i].right=NULL;
M.rhead[i].down=NULL;
}
for(int i=0;i<n;++i)
{
M.chead[i].right=NULL;
M.chead[i].down=NULL;
}
OLNode *temp_r[maxSize];//建立列链表的赋值指针数组
for(int j=0;j<n;++j)
temp_r[j]=&(M.chead[j]);
for(int i=0;i<m;++i) //m表示的是行
{
OLNode *c=&(M.rhead[i]);
for(int j=0;j<n;++j) //n表示的是列
{
if(A[i][j]!=0)
{
OLNode *p=(OLNode *)mall0c(sizeof(ONLode));
p->row=i;
p->col=j;
p->val=A[i][j];
p->down=NULL;
p->right=NULL;
c->right=p;
c=p;
temp_r[j]->down=p;
temp_r[j]=p;
}
}
}
return 1;
}