压缩矩阵的转置

本文探讨了压缩矩阵的概念,并详细解释了如何进行压缩矩阵的转置操作。通过实例分析,展示了在C++和C语言中实现这一过程的关键步骤和技术要点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

压缩矩阵的转置

#include"stdio.h"
#include"stdlib.h"

#define OK 1
#define ERROR -1
#define OVERFLOW -2

//压缩矩阵的顺序存储表示
typedef int Status;
typedef int Elem;
#define MAXSIZE 100//非零元个数的最大值为100

typedef struct{
	/*
	定义矩阵中一个非零元的结构
	i为行下标  j为列下标  e为该元素的值
	*/
	int i, j;
	Elem e;
}Triple;
typedef struct{
	/*
	定义矩阵的结构
	data为压缩矩阵,data[0]未被占用
	mu nu tu 矩阵的行数、列数和非零元个数
	*/

	Triple data[MAXSIZE + 1];//非零元三元组表,data[0]未被占用
	int mu, nu, tu;//矩阵的行数、列数和非零元个数 
}TMatrix;
//基本操作的函数原型说明---------------------------- 

//创建矩阵 
Status CreateTMatrix(TMatrix &M);

//销毁矩阵
Status DestoryTMatrix(TMatrix &M);

//输出矩阵
Status PrintTMatrix(TMatrix &M);

//转置矩阵 
Status TransposeTMatrix(TMatrix M, TMatrix &T);

//快速转置矩阵
Status FastTransposeTMatrix(TMatrix M, TMatrix &T);

//菜单
void menu()
{
	printf("1-----创建矩阵\n");
	printf("2-----销毁矩阵\n");
	printf("3-----输出矩阵\n");
	printf("4-----转置矩阵\n");
	printf("5-----快速转置矩阵\n");
	printf("-----退出输出一个负数!\n");
}

//主函数--------------------------------------- 
int main()
{
	//初始化
	int i = 0;
	TMatrix M;
	TMatrix T;

	int choice;
	while (1){
		//菜单
		menu();
		printf("请输入你要进行的操作:");
		scanf("%d", &choice);
		if (choice <= 0){
			printf("退出成功\n");
			return 0;
		}
		switch (choice)
		{
		case 1:
		{
				  i = CreateTMatrix(M);
				  if (i == 1)
				  {
					  printf("创建成功\n");
				  }
				  break;
		}
		case 2:
		{
				  i = DestoryTMatrix(M);
				  if (i == 1)
				  {
					  printf("销毁成功\n");
				  }
				  break;
		}
		case 3:
		{
				  i = PrintTMatrix(M);
				  break;
		}
		case 4:
		{
			{
				printf("转置前:\n");
				i = PrintTMatrix(M);
				i = TransposeTMatrix(M, T);
				printf("转置后:\n");
				i = PrintTMatrix(T);
			}
				  break;
		}
		case 5:
		{
			{
				printf("快速转置前:\n");
				i = PrintTMatrix(M);
				i = FastTransposeTMatrix(M, T);
				printf("快速转置后:\n");
				i = PrintTMatrix(T);
			}
				  break;
		}
		default:
		{
				   printf("选择失败,请重新选择!\n");
				   break;
		}
		}
		//system("pasuse");//请按任意键结束 
		//system("cls");//清屏 
	}
	return 0;
}
//-------基本操作的算法描述

//创建矩阵
Status CreateTMatrix(TMatrix &M)
{

	M.data[0].i = M.data[0].j = 0;//方便比较 

	int num = 1;

	while (1)
	{
		//检查非零元个数是否小于等于行数乘以列数
		printf("请输入矩阵的行数,列数和非零元个数:\n");

		scanf("%d", &M.mu);
		scanf("%d", &M.nu);
		scanf("%d", &M.tu);
		if (M.nu*M.mu<M.tu)
		{
			printf("输入错误,非零元素个数要小于等于行数乘以列数,请从新输入!\n");
			continue;
		}
		else
		{
			printf("矩阵规模限定成功\n");
			break;
		}
	}
	//输入数据
	while (num <= M.tu)
	{
		printf("请输入第%d个元素的行下标,列下标和元素值(按行序输入,且下标递增):\n", num);
		scanf("%d%d%d", &M.data[num].i, &M.data[num].j, &M.data[num].e);
		if (M.data[num].i<M.data[num - 1].i)
		{
			//行下标递减,报错
			printf("该元素行下标输入错误,请重新输入\n");
		}
		else if (M.data[num].i == M.data[num - 1].i){
			//行下标相等,则列下标不可小于或等于上一个元素的列下标 
			if (M.data[num].j <= M.data[num - 1].j || M.data[num].j>M.nu){
				//列下标递减或重复,或者列下标超出列数范围,都会报错
				printf("该元素下标输入错误,请重新输入\n");
			}
			else{
				//列下标递增,输入成功
				num++;
			}
		}
		else if (M.data[num].i>M.mu){
			//行下标超出行数范围
			printf("该元素行下标输入错误,请重新输入\n");
		}
		else{
			//行下标递增,则只需要控制列下标不超出范围即可
			if (M.data[num].j >= 1 && M.data[num].j <= M.nu){
				//输入成功
				num++;
			}
			else{
				printf("该元素列下标输入错误,请重新输入\n");
			}
		}
	}
	return OK;
}
//销毁矩阵

Status DestoryTMatrix(TMatrix &M)
{
	M.mu = 0;
	M.nu = 0;
	M.tu = 0;
	return OK;
}

//输出矩阵
Status PrintTMatrix(TMatrix &M)
{
	int num = 1;
	for (int row = 1; row <= M.mu; row++)
	{
		for (int col = 1; col <= M.nu; col++)
		{
			if (col == M.data[num].i && row == M.data[num].j)
			{
				//输出数据
				printf("%d", M.data[num].e);
				num++;
			}
			else{
				printf("0");
			}
			printf("	");
			if (col == M.nu){
				//一列输出后换行
				printf("\n");
			}
		}
	}
	return OK;
}

//转置矩阵
Status TransposeTMatrix(TMatrix M, TMatrix &T)
{
	int num = 1;
	T.mu = M.nu;
	T.nu = M.mu;
	T.tu = M.tu;
	if (T.tu)
	{
		for (int col = 0; col <= M.nu; col++)
		{
			//每行
			for (int sum = 1; sum <= M.tu; sum++)
			{
				//遍历所有的数据
				if (M.data[sum].j == col){
					T.data[num].i = M.data[sum].j;
					T.data[num].j = M.data[sum].i;
					T.data[num].e = M.data[num].e;
					num++;
				}
			}
		}
	}
	return OK;
}

//快速转置矩阵
Status FastTransposeTMatrix(TMatrix M, TMatrix &T)
{
	T.mu = M.nu;
	T.nu = M.mu;
	T.tu = M.tu;
	int q = 0;
	int col = 0;
	int num[MAXSIZE + 1];
	int cpot[MAXSIZE + 1];
	for (int col = 1; col <= M.mu; col++)
	{
		//清空num
		num[col] = 0;
	}
	for (int t = 1; t <= M.tu; t++)
	{
		//求M中每一列含非零元素个数
		num[M.data[t].j]++;
	}
	cpot[1] = 1;
	for (int col = 2; col <= M.nu; col++)
	{
		//求第col列中第一个非零元在T.data中的序号
		cpot[col] = cpot[col - 1] + num[col - 1];
	}
	for (int p = 1; p <= M.tu; p++)
	{
		col = M.data[p].j;
		q = cpot[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;
		cpot[col]++;
	}
	return OK;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

彭就是我的姓i

你的鼓励是我创作的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值