稀疏矩阵
稀疏矩阵时矩阵中的一种特殊情况,其非零元素的个数远远小于零元素个数。
![](https://i-blog.csdnimg.cn/blog_migrate/4c60a4f5d945da4d16f144c39ea1e4d3.png)
稀疏矩阵的存储结构
1.顺序存储
//非零元素三元组的结构定义
struct Triple{
int row,col;
ElemType val;
}
/*其中row代表行号,col代表列号,val用来存储元素值*/
//稀疏矩阵的顺序存储类型定义
struct SMatrix {
int m,n,t;
struct Triple sm[MaxTerms+1];
}
/*m,n,t域分别用来存储稀疏矩阵的行数,列数,非零元素个数,sm数组域用来顺序存储每个三元组元素。*/
![](https://i-blog.csdnimg.cn/blog_migrate/1be89f6d78b694f767871a8c217cc07c.png)
2.链接存储
(1)带行指针向量的链接存储
//三元组结点类型定义
struct TripleNode{
int row,col;
ElemType val;
struct TripleNode* next;
}
//带行指针向量的链接存储结构类型定义
struct LMatrix{
int m,n,t;
struct TripleNode* lm[MaxRows+1];
}
/*lm向量用来存储m个行单链表的表头指针*/
![](https://i-blog.csdnimg.cn/blog_migrate/94adf48a285e0681a2e53f84a84d5eeb.png)
(2)十字链接存储
//结点类型定义
struct CrossNode{
int row,col;
ElemType val;
struct CrossNode *down,*right;
}
/*down域用来存储指向下同一列下一个结点的指针,right域用来存储指向同一行下一个结点指针*/
//十字链接存储结构类型定义
struct CLMatrix{
int m,n,t;
struct CrossNode* rm[MaxRows+1];
struct CrossNode* cm[MaxColumns+1];
}
![](https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1534147096076&di=7799e5c5f1b355fbce05d98837a386b5&imgtype=0&src=http%3A%2F%2Fwww.educity.cn%2Farticle_images%2F2014-03-28%2Fe6b49edb-1733-4a18-a2c7-c39dea6f4d66.jpg)
稀疏矩阵的运算
1.初始化运算
稀疏矩阵的存储类型不同,其初始化过程也不同,对于SMatrix类型对象,初始化过程为:
void InitMatrix(struct sMatrix* M){
M->m = 0;M->n = 0;M->t = 0;
}
对于LMatrix类型对象,初始化为:
void InitMartix(struct sMatrix* M){
int i;
M->m = 0;M->n = 0;M->t = 0;
for(i=1;i<=MaxRows;i++)
M->li[i] = NULL;
}
对于CLMatrix类型对象,初始化为:
void InitMartix(struct sMatrix* M){
int i;
M->m = 0;M->n = 0;M->t = 0;
for(i=1;i<=MaxRows;i++)
M->rm[i] = NULL;
for(i=1;i<=Maxcolums;i++)
M->cm[i] = NULL;
}
2.稀疏矩阵的建立
对于SMatrix类型存储
void InputMartix(struct sMatrix* M ,int m,int n){
int k = 0;
int row,col;
ElemType val;
M->m = m;M->n = n;
printf("输入每个三元组:");
scanf("%d%d%d",&row,&col,&val);
while(row != 0){
k++;
M->sm[k].row = row;
M->sm[k].col = col;
M->sm[k].val = val;
scanf("%d%d%d",&row,&col,&val);
}
}
对于十字链接存储
void InputMatrix(struct CLMatrix* M,int m,int n){
int k = 0;
int row ,col;
ElemType val;
M->m = m;M->n = n;
printf("输入每个三元组:");
scanf("%d%d%d",&row,&col,&val);
while(row != 0){
struct CorssNode *cp ,*newp;
k++;
//得到和建立一个新结点
newp = (struct CrossNode*)malloc(sizeof(struct CrossNod));
newp->row = row;
newp->col = col;
newp->val = val;
newp->right = ewp->dow = NULL;
//把新结点链接到所在行单链表末尾
cp = M->rm[row];
if(cp == NULL){
M->rm[row] = newp;
}
else{
while(cp->right != NULL)
cp = cp->right;
cp->right = newp;
}
//把新结点链接到所在列单链表的末尾
cp = M->cm[col];
if(cp == NULL){
M->cm[col] = newp;
}
else{
while(cp->down != NULL)
cp = cp->down;
cp->down = newp;
}
//输入下一个三元组
scanf("%d%d%d",&row,&col,&val);
}
M->t = k;
}
3.稀疏矩阵的输出
按三元组线性表格式输出,则对于采用顺序存储的稀疏矩阵,输出算法如下:
void OutputMatrix(struct SMatrix* M){
int i;
printf("(");
for(i=1;i<M->t;i++){
printf("(%d,%d,%d),",M->sm[i].row,M->sm[i].col,M->sm[i].val);
}
if(M->t != 0){
printf("(%d,%d,%d),",M->sm[M->t].row,M->sm[M->t].col,M->sm[M->t].val)
}
printf(")\n");
}
带行指针向量的链接存储,输出算法如下:
void OutputMatrix(struct LMatrix* M){
int i;
struct TripleNode *p;
printf("(");
for(i=1;i<M->m;i++){
for(p=M->lm[i];p!=NULL;p=p->next)
printf("(%d,%d,%d),",p->row,p->col,p->val);
}
printf(")\n");
}