【数据结构】矩阵快速转置算法实现

实验名称:矩阵快速转置算法实现

实验

  • 实验目的

二、实验环境

1、visual studio2019

三、实验内容

1. 实现矩阵快速转置

源程序:

// ConsoleApplication2.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。

//矩阵的快速转置算法实现;



#include <iostream>

using namespace std;

#define MAXSIZE 12500

#define OK 1

typedef int Status;

typedef struct {

    int i, j;

    int e;



}Triple;//三元组

typedef struct {

    Triple data[MAXSIZE+1];//这个Data是什么,竖着的一整行

    int mu, nu, tu;//矩阵行数列数和非零元个数



} TMatrix;//三元组矩阵吗

/*做到转置1.将矩阵行和列的值交换,2.将元祖中i和j的值交换3,重新排列三元组之间的次序*/

/*Status TransposeMartix(TMatrix M, TMatrix& T)

{   

    T.mu = M.mu;

     T.nu = M.nu;

     T.tu = M.tu;

     if (T.tu) {

         int q = 1;

         for (int col = 1; col <= M.nu; col++)//why ++col,第一个元素不需要变换?

         {

             for (int p = 1; p <= M.mu; p++)//应该是mu?

             {

                 if (M.data[p].j == col)

                 {

                     T.data[q].i = M.data[p].j;

                     T.data[q].j = M.data[p].i;

                     T.data[q].e = M.data[p].e;

                     ++q;

                 }

             }

         }

     }



    return OK;

}*/

//首先需要先计算同一列的个数有多少,放到num(col)里,然后再放当前位置在表中,并更新

//要创建一个表

//疑问点;哪个是矩阵哪个是三元组,想计算同一列有多少个怎么计算

//循环顺序扫描,col=M.data[p].j col++遇到了同一个就+1;但是顺序怎么办,哦哦主列已有顺序 放一个cpot[col]

// 下一个cpot[col]=cpot[col-1]+num[cpot-1]上一个第一个位置加上非零元的数量就等于下一个非零元的位置【指在三元组表里】

//如何放进去cpot[col]

//② 三元表T可能没有初始化,这句的意思是将矩阵M的行数,列数,以及非零元个数传给矩阵T,使其初始化。

//③ T.tu为真时,即矩阵M中至少存在一个非零元。



TMatrix TransposeMartix(TMatrix M, TMatrix& T)

{

    T.mu = M.nu;

    T.nu = M.mu;

    T.tu = M.tu;//initialize

    int num[50];

    int cpot[50];

    if (T.nu) {

        for (int col = 1; col <= T.mu; ++col)//遍历每一行

        {  //初始化这个

            num[col] = 0;

        };

        for (int t = 1; t <= T.mu; ++t) {

            ++num[M.data[t].j];//smart step!

        }

        cpot[1] = 1;

        for (int col = 2; col <= M.nu; ++col) {

            cpot[col] = cpot[col - 1] + num[col - 1];

        }

        for (int p = 1; p <= T.mu; ++p) {

            int col = M.data[p].j;

            T.data[cpot[col]].i = col;

            T.data[cpot[col]].j = M.data[p].i;

            T.data[cpot[col]].e = M.data[p].e;

            ++cpot[col];



            

        }

    }

    cout << "转置成功" << endl;

    return T;

}



int main()

{   

    TMatrix M;

    TMatrix T;

    M.mu = 2;

    M.nu= 3;

    M.tu = 4;



    M.data[0].i = 1;

    M.data[0].j = 2;

    M.data[0].e = 1;



    M.data[1].i = 2;

    M.data[1].j = 2;

    M.data[1].e = 3;



    M.data[2].i = 3;

    M.data[2].j = 1;

    M.data[2].e = 6;



    M.data[3].i = 3;

    M.data[3].j = 2;

    M.data[3].e = 5;

    

    T = TransposeMartix(M, T);

    printf("使用快速转置:\n");

    for (int i = 1; i <= M.nu; i++) {

        printf("(%d,%d,%d)\n", T.data[i].i, T.data[i].j, T.data[i].e);

    }



}







运行结果截图:

运行结果分析:

快速转置是为了解决用传统方法1.冒泡排序遍历时间复杂度高o(n2

                              三元组ij互换后再根据i列数大小重新排序

  1. o(n*t

{1}先用for (int t = 1; t <= T.mu; ++t) {

            ++num[M.data[t].j];//smart step!

        }

获得每一个相同j值的个数,用num[]储存。如num[2]=3,即原三元组矩阵中j为2的行数为3。转置后代表需要留三行空位给i=2的元组。

{2}用cpot[1] = 1;

        for (int col = 2; col <= M.nu; ++col) {

            cpot[col] = cpot[col - 1] + num[col - 1];

        }

这个来获得每个转置后的i所需要的行位置,比如原来i=2时位置是在第二排,即cpot[2]=cpot[1]+num[1]=2;那么如果num[2]=3,即i=2的有三行,那么下一个i值就应该从cpot[2]+num[2]=5开始,即cpot[3]=5。

{3}for (int p = 1; p <= T.mu; ++p) {

            int col = M.data[p].j;

            T.data[cpot[col]].i = col;

            T.data[cpot[col]].j = M.data[p].i;

            T.data[cpot[col]].e = M.data[p].e;

            ++cpot[col];

            

        }

用这个来把相应的原来矩阵M的data[].i j e按照cpot里标记的位置赋给新的转置矩阵T。因为原来矩阵M同i值元组的j也按顺序排列,所以不需要考虑顺序赋值会乱的问题。

{4}最后测试输出矩阵  

for (int i = 1; i <= M.nu; i++) {

        printf("(%d,%d,%d)\n", T.data[i].i, T.data[i].j, T.data[i].e);

    }

}

通过实验练习了快速排序算法,同时加深了对时间复杂度的理解。

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值