稀疏矩阵及其转置算法

稀疏矩阵的构造

typedef struct triple//三元数组
{
    int i;
    int j;
    int num;
}triple;
typedef struct smatrix
{
    triple data[20];
    int m;//原矩阵行数
    int n;//原矩阵列数
    int p;//非零元素的个数

}smatrix;
void create(int a[][7],int h,int l,smatrix*sm);
void print(smatrix*sm);
void transpose(smatrix*s,smatrix*t);
void Qtranspose(smatrix*s,smatrix*t);
int main()
{
    smatrix sm,t;
    int a[6][7]={{0,12,0,0,0,0,0},{0,0,0,0,0,0,0},{-3,0,0,0,0,14,0},
    {0,0,24,0,0,0,0},{0,18,0,0,0,0,0},{15,0,0,-1,0,0,0}};
    create(a,6,7,&sm);

     Qtranspose(&sm,&t);
     print(&t);


}

稀疏矩阵的创建

void create(int a[][7],int h,int l,smatrix*sm)

{sm->p=0;
sm->m=h;
sm->n=l;
    for(int i=0;i<sm->m;i++)//一行一行遍历整个矩阵,将不为0的元素放进三元数组中
    {

        for(int j=0;j<sm->n;j++)
        {
            if(a[i][j]!=0)
            {

                sm->data[sm->p].i=i;
                sm->data[sm->p].j=j;
                sm->data[sm->p].num=a[i][j];
                sm->p++;

            }
        }
    }
}
void print(smatrix*sm)
{
    for(int k=0;k<sm->p;k++)
    {
        printf("%d %d %d\n",sm->data[k].i,sm->data[k].j,sm->data[k].num);
    }
}

稀疏矩阵的普通转置

  • 不断遍历三元数组,从0下标开始查找原数组中j为0的所有元素,依次放入新三元数组中并调换i和j的位置
void transpose(smatrix*s,smatrix*t)
{
    int k=0;
    t->m=s->m;
    t->n=s->n;
    for(int i=0;i<s->n;i++)
    {
        for(int j=0;j<s->p;j++)
        {
            if(s->data[j].j==i)
            {
                t->data[k].i=s->data[j].j;
                t->data[k].j=s->data[j].i;
                t->data[k].num=s->data[j].num;
                k++;
            }
        }
    }
    t->p=k;
}

稀疏矩阵的转置算法

  • 遍历一次三元数组,用num[]记录列的个数,如第二列中的元素有几个,num[i]就表示第二列有几个不为0的元素
  • 再次遍历原三元数组,得到列数后就将上其之前的所有num[]值,确定放入新三元数组中的第几列,直接放入即可,但要注意判断一下是不是该位置已经放过一个了,如果放过了,就pos++
void Qtranspose(smatrix*s,smatrix*t)
{
    t->m=s->n;
    t->n=s->m;
    t->p=s->p;
    int *num=(int *)malloc(sizeof(int)*s->p);
    for(int i=0;i<s->p;i++)
    {
        num[i]=0;
    }
    //将每一列中不为0的元素的个数放入num[]中
    for(int i=0;i<s->p;i++)
    {
        num[s->data[i].j]++;

    }
    //得到该列具体的位置pos
    for(int i=0;i<s->p;i++)
    {
        int m=s->data[i].j;int pos=0;
        if(m!=0)
        {
            for(int n=0;n<m;n++)
        {
            pos=pos+num[n];
            if(t->data[pos].i==m)
            {
                pos++;
            }
        }
        }
        else
        {
            pos=0;
            if(t->data[pos].i==0)
            {pos++;}
        }
        t->data[pos].i=s->data[i].j;
        t->data[pos].j=s->data[i].i;
        t->data[pos].num=s->data[i].num;
    }

}

你可能感兴趣的:(数据结构,数据结构,算法)