三元组顺序表快速转置

三元组顺序标的快速转置

对于稀疏矩阵,为了节省空间,通常使用 三元组顺序表 和 十字链表存储。

对于矩阵,转置运算是很常见的。对于三元组顺序表,如果仅仅将顺序表中每个元素的行号和列号进行交换,生成的新三元组顺序表不是真正的三元组顺序表,因为,行号不是依次递增的,当然,也可以先进行交换行号列号,再对它进行按行号升序的排序,但涉及到排序,就会很麻烦,所以,介绍一种快速转置的方法。

如果要遍历一次三元组顺序表,就要将其转置成功,那么,在遍历每一个元素时,除了交换它的行号和列号,还要将它放到新的顺序表中的特定位置,但是我们怎么知道这个位置呢,我们可以使用一个pos数组进行定位,即pos[列号]就是这个元素在新的三元组顺序表中的位置。

例如,现在第一次遍历到列号为n的元素,那它应该放在哪个位置?这与列号为n-1的最后一个元素的位置有关,要知道列号为n-1的最后一个元素的下一个位置,就要知道列号为n-1的起始位置,和列号为n-1的元素的个数,所以,要引进一个新的数组num,则 pos[n]=pos[n-1]+num[n-1]

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

#define MAXSIZE 100

/****类型声明****/
typedef struct{

    int row,col;
    int value;
}Triple;

typedef struct{

    Triple data[MAXSIZE+1];
    int rows,cols,nums;
}TSMatrix;

/****函数声明****/
    //初始化三元组顺序表 
    //@flag 1表明需要进行输入,0表示不需要进行输入 
TSMatrix * Init(int flag);

    //对顺序表进行排序,这个在初始化中用到
void Sorttable(TSMatrix *A,int left,int right);

    //按照矩阵的形式输出三元组顺序表
void Print(TSMatrix *A);

    //矩阵转置,将结果存到B中
void TransposeTSMatrix(TSMatrix *B,TSMatrix *A);


int main(void){

    TSMatrix *A=Init(1);
    Print(A);
    TSMatrix *B=Init(0);
    TransposeTSMatrix(B,A);
    Print(B);

    return 0;
}


TSMatrix * Init(int flag){

    TSMatrix *A=(TSMatrix *)malloc(sizeof(TSMatrix));
    if(flag){

        printf("请输入矩阵的行数和列数:");
        int rows,cols;
        scanf("%d%d",&rows,&cols);
        A->rows=rows;
        A->cols=cols;

        printf("请输入矩阵非0元素个数:");
        int nums;
        scanf("%d",&nums);
        A->nums=nums;

        printf("请输入非零元素所在的行数,列数以及该元素的值:\n");
        int row,col,value;
        printf("row col value\n");
        for(int i=0;i<nums;++i){

            scanf("%d%d%d",&row,&col,&value);
            A->data[i+1].row=row;
            A->data[i+1].col=col;
            A->data[i+1].value=value;
        }

        Sorttable(A,1,A->nums);
        //在输入时,不一定按照行号升序输入,这里用快速排序进行排序
    }

    return A;
}

void Print(TSMatrix *A){

    int k=1;//用于遍历三元组顺序表
    printf("\n  ");
    for(int i=1;i<A->cols+1;++i)
        printf("%5d",i);
    printf("\n");
    for(int i=1;i<10*A->cols;++i)
        printf("-"); 
    for(int i=1;i<A->rows+1;++i){
        printf("\n%d|",i);
        for(int j=1;j<A->cols+1;++j){

            if(A->data[k].row==i && A->data[k].col==j && k<A->nums+1)
                printf("%5d",A->data[k++].value);
            else
                printf("%5d",0);
        }
    }
    printf("\n");
    for(int i=1;i<10*A->cols;++i)
        printf("-"); 
    return ;
}

void TransposeTSMatrix(TSMatrix *B,TSMatrix *A){//将A的转置存在B里

    B->rows=A->cols;
    B->cols=A->rows;
    B->nums=A->nums;

    int num[MAXSIZE]={0};
    int position[MAXSIZE]={0,1};

    //计算num数组
    for(int i=1;i<A->nums+1;++i)
        ++num[A->data[i].col];
    //计算pos数组,将pos[1]初始化为1
    for(int i=2;i<A->cols+1;++i)
        position[i]=num[i-1]+position[i-1];

    int pos;//记录转置后的位置
    for(int i=1;i<A->nums+1;++i){

        pos=position[A->data[i].col];
        B->data[pos].col=A->data[i].row;
        B->data[pos].row=A->data[i].col;
        B->data[pos].value=A->data[i].value;

        ++position[A->data[i].col];
    }
} 

void Sorttable(TSMatrix *A,int left,int right){

    if(left>=right)
        return ;

    Triple temp=A->data[left],t;
    int i=left,j=right;
    while(i<j){

        while(A->data[j].row>=temp.row && i<j)
            --j;
        while(A->data[i].row<=temp.row && i<j)
            ++i;

        t=A->data[j];
        A->data[j]=A->data[i];
        A->data[i]=t;
    }
    A->data[left]=A->data[i];
    A->data[i]=temp;

    Sorttable(A,left,i-1);
    Sorttable(A,i+1,right);

    return ;
}
  • 7
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值