您的位置:首页 > 理论基础 > 数据结构算法

矩阵转置(数据结构课本内容)

2015-10-02 20:28 295 查看
//最近有人问我课本矩阵转置的相关内容,表示确实课堂上没有理顺,所以趁着假期整理一二。

#include <iostream>
using namespace std;
struct Terms//Terms是稀疏矩阵的顺序表存储
{
int row,col;
int value;
};
class SeqTriple//注意这里的SeqTriple就是指的保存在顺序表里的稀疏矩阵的非零元素操作,而怎样扫描非零元素到顺序表中不用关心,因为二维数组已经存不下稀疏矩阵了,所以必然不能直接扫描非零元素
{
private:
int n,m,t,maxsize;//n是原稀疏矩阵的行数
Terms *trip;//m是原稀疏矩阵的列数(因为如果我知道顺序表一共有0~7但是如果不知道原来的行数(行优先存储),列数(列优先存储),那么原稀疏矩阵第9行,第10行也可能有元素,全是0)
//t是原稀疏矩阵有多少非零元素,表现在顺序表上,就是顺序表下标+1
//maxsize是最大容量,就是我最多开辟多大空间来存储,在这里表现的不是很明显
public:
SeqTriple(int msize);//这里是初始化线性表的内容,主要是找到稀疏矩阵中不为0的数,存储到表中,但我们只要建表即可
void Transpose();
void Transpose2();
};
SeqTriple::SeqTriple(int msize)
{
maxsize=msize;
n=7;
m=6;
t=8;
trip=new Terms[maxsize];
trip[0].row=0;
trip[0].col=0;
trip[0].value=16;
trip[1].row=0;
trip[1].col=3;
trip[1].value=22;
trip[2].row=0;
trip[2].col=5;
trip[2].value=-16;
trip[3].row=1;
trip[3].col=1;
trip[3].value=12;
trip[4].row=1;
trip[4].col=2;
trip[4].value=3;
trip[5].row=2;
trip[5].col=3;
trip[5].value=-8;
trip[6].row=4;
trip[6].col=0;
trip[6].value=91;
trip[7].row=6;
trip[7].col=2;
trip[7].value=15;
}
void SeqTriple::Transpose()//按照列优先存储就是列数为0,1,2,3,4的排列,所以我第i次扫描就找到列数为i的元素,把它的行列对换,放入新表中
{
int sum=0;
int i,j;
Terms *b;//临时存储
b=new Terms[t];
cout<<"原矩阵为:"<<endl;
for (i=0;i<t;i++)
cout<<trip[i].row<<" "<<trip[i].col<<" "<<trip[i].value<<" "<<endl;
for (i=0;i<m;i++)//每一次扫描第i列的所以扫描i次
for (j=0;j<t;j++)//每一次都是从头到尾把表扫描一遍
{
if (trip[j].col==i)//如果第i次扫描找到第i列的数(该数行为j)
{
b[sum].row=trip[j].col;
b[sum].col=trip[j].row;
b[sum++].value=trip[j].value;
}
}
cout<<"转置后为:"<<endl;
for (i=0;i<sum;i++)
cout<<b[i].row<<" "<<b[i].col<<" "<<b[i].value<<" "<<endl;
m=n;
n=m;

}
void SeqTriple::Transpose2()//该转置方法用了两个数组,num[]和k[]首先num[]的作用是统计第i列有多少个非零元素,k[i]是统计第i列之前有一共多少个非零元素
//这样我们可以推出公式,k[i+1]=num[i]+k[i](第i+1列之前的非零元素=第i列之前的非零元素+第i列的非零元素,而k[0]=0)
//那么k[]有什么用呢,当我们传入trip[j].col时,我们想知道原来第j行元素到底在新表中的第几行,所以i=trip[j].col,而k[i]是之前有多少个非零元素,那么它自然就是后面一个,
//值得注意的是每一列不止一个数,所以初始这一列元素之前有n个元素,同时要让这一列的元素下标加1,因为在这一列中他们也算后面的了。
{
int num[100];
int k[100],i,j;
Terms *b;
cout<<"原矩阵的为:"<<endl;
for (i=0;i<t;i++)
cout<<trip[i].row<<" "<<trip[i].col<<" "<<trip[i].value<<endl;
b=new Terms[t];
for (i=0;i<m;i++)
num[i]=0;
for (i=0;i<t;i++)
num[trip[i].col]++;//有点像桶排序
k[0]=0;
for (i=1;i<m;i++)
k[i]=k[i-1]+num[i-1];//求出k[],第i列前面有几个元素(即知道列就知道排第几个)
for (i=0;i<t;i++)
{
j=k[trip[i].col]++;//它是第几行,同时以后第i列的元素排名得往后一个(即知道了原来的列,就能知道它在现在的表中排第几个,而如果之前已经传了一个列,那么同样是这个列的得往后排)
b[j].col=trip[i].row;
b[j].row=trip[i].col;
b[j].value=trip[i].value;

}
cout<<"转制后为:"<<endl;
for (i=0;i<t;i++)
cout<<b[i].row<<" "<<b[i].col<<" "<<b[i].value<<endl;
return;
}
int main()
{

SeqTriple A(100);
A.Transpose();
A.Transpose2();
return 0;

}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: