4.8 KiB
4.8 KiB
原创
: 第五章 数组、矩阵与广义表
第五章 数组、矩阵与广义表
一、矩阵的压缩存储
//矩阵定义
#define m 4
#define n 5
int A[m][n];
//1.矩阵的转置
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];
}
//2.矩阵相加
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;i<n;++j) C[i][j]=A[i][j]+B[i][j];
}
//3.矩阵相乘A:M*N,B:N*K,C:M*K
void mutmat(int C[][maxSize],int A[][maxSize],int B[][maxSzie],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];
}
}
}
二、特殊矩阵和稀疏矩阵
//1.三元组表示法
typedef struct
{
int val;
int i,j;
}Trimat;
Trimat trimat[maxterms+1];
//trimat[k].i和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]为原矩阵非零元素个数,矩阵行数和列数
//如果矩阵元素为float类型,则定义为:
//float trimat[maxterms+1][3];
(int)trimat[k][1];//需要进行强制类型转换
(int)trimat[k][2];
建立三元组:
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)
{
if(A[i]A[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(float 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 QNode
{
int row, col;//行数,列数
struct OLNode *right, *down;
float val;
}OLNode;
//头结点结构定义
typedef struct
{
OLNode *rhead, *chead;//指向两头结点数组的指针
int m,n,k; //矩阵行数、列数以及非零结点总数
}CrossList;
//example:给定一个稀疏矩阵A,其尺寸为m*n,非零元素个数为k,建立其对应的十字链表存储结构
int createcrossListmat(float A[][maxSize],int m, int n,int k,CrossList &M)
{
if(M.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.rhead=(OLNode*)malloc(sizeof(OLNode)*m)))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)
{
OLNoden *c=&(M.rhead[i]);
for(int j=0;j<n;++j)
{
if(A[i][j]!=0)
{
OLNode *p=(OLNode*)malloc*(sizeof(OLNode));
p->row=i;
p->col=j;
p->val=A[i][j];
p->down=NULL;
p->right=NULL;
c->right=p;
c=p;
temp_r[i]->down=p;
temp_r[j]=p;
}
}
}
return 1;
}
四、广义表
广义表:表元素可以是原子或者广义表的一种线性表的扩展结构
广义表的深度:表中最上层元素的个数
广义表的长度:表中括号的最大层数
表头和表尾:当广义表非空时,第一个元素为广义表的表头,其余元素组成的表是广义表的表尾
-
头尾链表存储结构(类似于不带头结点的单链表)两种结点:
原子结点:标记域和数据域
广义表结点:标记域、头指针、尾指针
扩展线性表存储结构(类似于带头结点的单链表存储结构)l两种结点:原子结点:标记域、数据域和尾指针域
广义表结点:标记域、头指针域和尾指针域