2021-02-27 15:01:45 +00:00
|
|
|
|
# 原创
|
|
|
|
|
: 第五章 数组、矩阵与广义表
|
|
|
|
|
|
|
|
|
|
# 第五章 数组、矩阵与广义表
|
|
|
|
|
|
2024-07-03 09:49:47 +00:00
|
|
|
|
## 一、矩阵的压缩存储
|
2021-02-27 15:01:45 +00:00
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
//矩阵定义
|
|
|
|
|
#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];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
2024-07-03 09:49:47 +00:00
|
|
|
|
## 二、特殊矩阵和稀疏矩阵
|
2021-02-27 15:01:45 +00:00
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
//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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
2024-07-03 09:49:47 +00:00
|
|
|
|
## 三、十字链表
|
2021-02-27 15:01:45 +00:00
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
//普通结点定义
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
2024-07-03 09:49:47 +00:00
|
|
|
|
## 四、广义表
|
2021-02-27 15:01:45 +00:00
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
广义表:表元素可以是原子或者广义表的一种线性表的扩展结构 <br/> 广义表的深度:表中最上层元素的个数 <br/> 广义表的长度:表中括号的最大层数 <br/> 表头和表尾:当广义表非空时,第一个元素为广义表的表头,其余元素组成的表是广义表的表尾 <br/> - <br/> 头尾链表存储结构(类似于不带头结点的单链表)两种结点: <br/> 原子结点:标记域和数据域
|
2024-07-03 09:49:47 +00:00
|
|
|
|
<h3>广义表结点:标记域、头指针、尾指针</h3>
|
2021-02-27 15:01:45 +00:00
|
|
|
|
扩展线性表存储结构(类似于带头结点的单链表存储结构)l两种结点: <br/> 原子结点:标记域、数据域和尾指针域 <br/> 广义表结点:标记域、头指针域和尾指针域
|
|
|
|
|
|