数据结构实验 矩阵的转置

严书----数据结构----P98

这次的实验是完成稀疏矩阵的转置:

原理:首先稀疏矩阵的非零值远小于总个数的,所以可以用一个三元组将该矩阵存储起来,但是这样的话在进行转置的时候就没那么直观了,就不只是交换行列那样,所以就要用到今天的方法.如下:

下面用两种方法实现,一种是直接按照列的值进行重排,另一种是快速转置

储存压缩矩阵有两种方式,一种是用二维数组来储存三元组,另一种是直接写在结构体里

(注意:用二维数组储存三元组的方法很好用,使用于出现三个变量,eg:x,y,val这种形式,在ACM也经常用到)




方法一:

#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
/*
三元组传入一个稀疏矩阵,即不为零的个数<=0.05
把矩阵转化为转置矩阵,
注意:矩阵得设置一个具体矩阵出来
eg:10*10并将其打印出来.

步骤:
1.将矩阵的行列值相互交换,将每个三元组的i和j相互调换
2.重排三元组之间的次序便可实现矩阵的转置
*/

//终于成功....睡觉...一次是在for循环后面加了;,一次是for循环<=写成了<....循环还是要认真写啊,,,,
const int maxn = 10;

//对三元组的val值进行排序
//用第一种排序方法:按照原矩阵的列序来进行转置
void sort_triple(int (*pTriple)[3], int (*pnewTriple)[3])
{
	pnewTriple[0][0] = pTriple[0][1];
	pnewTriple[0][1] = pTriple[0][0];
	pnewTriple[0][2] = pTriple[0][2];
	if (pnewTriple[0][2])
	{
		int cnt = 1;
		for (int col = 1; col <= pTriple[0][1]; col++)//按原来的列来,对原来的每一列
		{
			for (int t = 1; t <= pTriple[0][2]; t++) //遍历所有非零数
			{
				if (pTriple[t][1] == col)//如果存入的值是属于这一列的
				{
					pnewTriple[cnt][0] = pTriple[t][1];
					pnewTriple[cnt][1] = pTriple[t][0];
					pnewTriple[cnt][2] = pTriple[t][2];
					cnt++;
				}
			}
		}
		//printf("cnt  %d  %d \n",cnt, pnewTriple[3][2]);
	}
}

int main()
{
	int matrix[10][10] = {
		{ 0,0,0,0,0,0,4,0,0,0 },
		{ 0,0,0,0,0,0,0,0,0,0 },
		{ 0,0,0,0,0,0,0,0,0,0 },
		{ 0,0,0,0,0,0,0,0,0,0 },
		{ 0,0,0,0,0,0,0,0,8,0 },
		{ 0,0,0,0,0,0,0,0,0,0 },
		{ 0,0,0,0,0,0,0,0,0,0 },
		{ 0,0,0,0,0,0,0,0,0,0 },
		{ 0,0,2,0,0,0,0,0,0,0 },
		{ 0,0,0,1,0,0,0,0,0,0 }
	};
	int triple[maxn + 1][3] = { maxn,maxn,0 }; //用于存储稀疏矩阵信息的三元组(矩阵压缩)

	//将已知的矩阵用三元组表示
	int cnt = 0;//矩阵的元素个数
	for (int i = 0; i < maxn; i++)
	{
		for (int j = 0; j < maxn; j++)
		{
			if (matrix[i][j])
			{
				triple[++cnt][0] = i;
				triple[cnt][1] = j;
				triple[cnt][2] = matrix[i][j];
			}
		}
	}
//	printf("%d  cnt \n", cnt);
	triple[0][2] = cnt;
	int newTriple[maxn+1][3];

	//对三元组的值进行排序
	sort_triple(triple,newTriple);

	//输出矩阵
	int new_matrix[maxn][maxn] = { 0 };
//	printf("%d   ... cnt", newTriple[0][2]);
	for (int i = 1; i <= newTriple[0][2]; i++)
	{
		int x = newTriple[i][0];
		int y = newTriple[i][1];
		int value = newTriple[i][2];
		new_matrix[x][y] = value;
	}
	puts("转置前:");
	for (int i = 0; i < maxn; i++)
	{
		for (int j = 0; j < maxn; j++)
		{
			printf("%d ", matrix[i][j]);
		}
		puts("");
	}
	puts("转置后:");
	for (int i = 0; i < maxn; i++)
	{
		for (int j = 0; j < maxn; j++)
		{ 
			printf("%d ", new_matrix[i][j]);
		}
		puts("");
	}

	system("pause");
	return 0;
}





方法二:








#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
//快速转置法
/*
三元组传入一个稀疏矩阵,即不为零的个数<=0.05
把矩阵转化为转置矩阵,
注意:矩阵得设置一个具体矩阵出来
eg:10*10并将其打印出来.

步骤:
1.将矩阵的行列值相互交换,将每个三元组的i和j相互调换
2.重排三元组之间的次序便可实现矩阵的转置
*/

//可以试一下这种用cmp进行排序的
/*
bool cmp(int(*a)[3], int(*b)[3])
{
if (*a + 0 < *b + 0) return true;
else if (*a + 0 == *b + 0)
return *a + 1 < *b + 1;
else return false;
}*/


const int maxn = 10;

typedef struct {
	int i, j;
	int val;
}Triple;

typedef struct {
	Triple data[maxn + 1];
	int row, col, sum;//行数,列数,非零元个数
}TSMatrix;


//对矩阵的val值进行排序
//用第二种排序方法:按照原矩阵的列序来进行转置
/*
M是原来的矩阵,T是新的矩阵
num[col]是M中第col列非零元的个数
cpot[col]是M中第col列第一个非零元在第二个b.data的位置
*/
void sort_triple(TSMatrix M, TSMatrix &T)//
{
	T.row = M.col;
	T.col = M.row;
	T.sum = M.sum;
	int num[maxn+1];//num[col]是M中第col列非零元的个数
	int cpot[maxn+1];//cpot[col]是M中第col列第一个非零元在b.data的位置
	if (T.sum)
	{
		for (int col = 1; col <= M.col; col++)	num[col] = 0;
		for (int i = 1; i <= M.sum; i++) num[M.data[i].j]++;//求M每一列的非零元个数
		cpot[1] = 1;
		for (int i = 2; i <= M.col; i++) cpot[i] = cpot[i - 1] + num[i - 1];
		for (int i = 1; i <= M.sum; i++)
		{
			int col = M.data[i].j;
			int tt = cpot[col];
			T.data[tt].i = M.data[i].j;
			T.data[tt].j = M.data[i].i;
			T.data[tt].val = M.data[i].val;
			cpot[col]++;//用掉一个,这一列非零元开始的位置就要增加一
		}//for
	}//if
}

int main()
{
	int matrix[10][10] = {
		{ 0,0,0,0,0,0,4,0,0,0 },
		{ 0,0,0,0,0,0,0,0,0,0 },
		{ 0,0,0,0,0,0,0,0,0,0 },
		{ 0,0,0,0,0,0,0,0,0,0 },
		{ 0,0,0,0,0,0,0,0,8,0 },
		{ 0,0,0,0,0,0,0,0,0,0 },
		{ 0,0,0,0,0,0,0,0,0,0 },
		{ 0,0,0,0,0,0,0,0,0,0 },
		{ 0,0,2,0,0,0,0,0,0,0 },
		{ 0,0,0,1,0,0,0,0,0,0 }
	};
	TSMatrix aa;
	int cnt = 0;//矩阵的元素个数

	for (int i = 0; i < maxn; i++)
	{
		for (int j = 0; j < maxn; j++)
		{
			if (matrix[i][j])
			{
				aa.data[++cnt].i = i;
				aa.data[cnt].j = j;
				aa.data[cnt].val = matrix[i][j];
			}
		}
	}
	aa.row = maxn;
	aa.col = maxn;
	aa.sum = cnt;

	TSMatrix new_aa;
	//对三元组的值进行排序
	sort_triple(aa, new_aa);

	//输出矩阵
	int new_matrix[maxn][maxn] = { 0 };
	for (int i = 1; i <= new_aa.sum; i++)
	{
		int x = new_aa.data[i].i;
		int y = new_aa.data[i].j;
		int value = new_aa.data[i].val;
		new_matrix[x][y] = value;
	}
	puts("转置前:");
	for (int i = 0; i < maxn; i++)
	{
		for (int j = 0; j < maxn; j++)
		{
			printf("%d ", matrix[i][j]);
		}
		puts("");
	}
	puts("转置后:");
	for (int i = 0; i < maxn; i++)
	{
		for (int j = 0; j < maxn; j++)
		{
			printf("%d ", new_matrix[i][j]);
		}
		puts("");
	}

	system("pause");
	return 0;
}



也可以试试下面这样用sort来排里面的val值.具体还没写完整,应该差不多这样

bool cmp(int(*a)[3], int(*b)[3])
{
if (*a + 0 < *b + 0) return true;
else if (*a + 0 == *b + 0)
return *a + 1 < *b + 1;
else return false;
}





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值