NOJ-稀疏矩阵转置-西工大数据结构

    上周就做完了,拖了一周今天才来写。题目如下:


    看一下题目,就是创建三元组表然后转置再输出。

    我采取的方法是,先得到矩阵每一列非0元的个数,那么每一列第一个元素在新的三元表中的位置就是上一列的非0元的个数加上上一列第一个元素在新三元表的位置之和。示例如下:


    

  以下是我的实现:

#include <stdio.h>
#include <stdlib.h>

struct Triple
{
    int ti;
    int tj;
    int value;
};

struct tripleList
{
    struct Triple T[2000];
    int li;
    int lj;
    int ln;
};

void createNewTripleList (struct tripleList *list1);
void printTripleList (struct tripleList *list);
void change (struct tripleList *list1,struct tripleList *list2,int colPot[]);
void run ();
void getColPot (struct tripleList *list,int colPot[]);

int main()
{
    run ();
    return 0;
}

void run ()
{
    int colPot[2000]={0};
    struct tripleList list1,list2;
    createNewTripleList (&list1);
    getColPot (&list1,colPot);
    change (&list1,&list2,colPot);
    printTripleList (&list2);
}

void createNewTripleList (struct tripleList *list1)
{
    int i=0,a,b,c;
    scanf ("%d%d",&(list1->li),&(list1->lj));
    while (1)
    {
        scanf ("%d%d%d",&a,&b,&c);
        if (a==0&&b==0&&c==0)
        {
            break;
        }
        list1->T[i].ti=a;
        list1->T[i].tj=b;
        list1->T[i].value=c;
        i++;
    }
    list1->ln=i;
}

void getColPot (struct tripleList *list,int colPot[])
{
    int n[2000]={0};
    int i,pre1=0,pre2=0;
    for (i=0;i<=list->ln-1;i++)
    {
        (n[list->T[i].tj])++;
    }
    for (i=0;i<=list->lj-1;i++)
    {
        colPot[i]=pre1+pre2;
        pre1=n[i];
        pre2=colPot[i];
    }
}

void printTripleList (struct tripleList *list)
{
    int i;
    for (i=0;i<=list->ln-1;i++)
    {
        printf ("%d %d %d\n",list->T[i].ti,list->T[i].tj,list->T[i].value);
    }
}

void change (struct tripleList *list1,struct tripleList *list2,int colPot[])
{
    int i,n;
    list2->li=list1->lj;
    list2->lj=list1->li;
    list2->ln=list1->ln;
    for (i=0;i<=list1->ln-1;i++)
    {
        n=colPot[list1->T[i].tj];
        list2->T[n].ti=list1->T[i].tj;
        list2->T[n].tj=list1->T[i].ti;
        list2->T[n].value=list1->T[i].value;
        (colPot[list1->T[i].tj])++;
    }
}

以下是各函数的注释:

void createNewTripleList (struct tripleList *list1)
{
    int i=0,a,b,c;
    scanf ("%d%d",&(list1->li),&(list1->lj));//输入行数和列数
    while (1)
    {
        scanf ("%d%d%d",&a,&b,&c);//输入三元表
        if (a==0&&b==0&&c==0)//当都为0时停止输入
        {
            break;
        }
        list1->T[i].ti=a;//行
        list1->T[i].tj=b;//列
        list1->T[i].value=c;//值
        i++;
    }
    list1->ln=i;//三元组表元素个数
}
void getColPot (struct tripleList *list,int colPot[])
{
    int n[2000]={0};
    int i,pre1=0,pre2=0;
    for (i=0;i<=list->ln-1;i++)//得到矩阵每列的非0元个数
    {
        (n[list->T[i].tj])++;
    }
    for (i=0;i<=list->lj-1;i++)
    {
        colPot[i]=pre1+pre2;//本列列第一个非0元素在新表的位置,上一列的非0元的个数加上上一列第一个元素在新三元表的位置
        pre1=n[i];
        pre2=colPot[i];
    }
}
void change (struct tripleList *list1,struct tripleList *list2,int colPot[])
{
    int i,n;
    list2->li=list1->lj;//行 列 个数赋值
    list2->lj=list1->li;
    list2->ln=list1->ln;
    for (i=0;i<=list1->ln-1;i++)//依次遍历原三元表
    {
        n=colPot[list1->T[i].tj];//得到当前元素在新三元表中位置
        list2->T[n].ti=list1->T[i].tj;//转置赋值
        list2->T[n].tj=list1->T[i].ti;
        list2->T[n].value=list1->T[i].value;
        (colPot[list1->T[i].tj])++;//位置自增,以便同列的下一个元素找到正确位置
    }
}
void printTripleList (struct tripleList *list)
{
    int i;
    for (i=0;i<=list->ln-1;i++)//遍历新三元表并输出
    {
        printf ("%d %d %d\n",list->T[i].ti,list->T[i].tj,list->T[i].value);
    }
}
void run ()
{
    int colPot[2000]={0};
    struct tripleList list1,list2;
    createNewTripleList (&list1);//创建三元表
    getColPot (&list1,colPot);//得到位置数组
    change (&list1,&list2,colPot);//转置
    printTripleList (&list2);//输出
}

    以上就是我的实现,希望给大家带来帮助。




猜你喜欢

转载自blog.csdn.net/qq_30180107/article/details/79917771