实验7、矩阵的2种转置运算 (4学时)

1)实验目的

      通过该实验,让学生理解矩阵压缩存储的概念、方法等相关知识,掌握用三元组表方式如何进行矩阵的压缩存储,并在此基础上进行转置操作,理解转置和快速转置两种矩阵转置算法的思想。

2)实验内容

用三元组表压缩存储矩阵,实现创建矩阵、显示以及教材中介绍的两种转置算法。

3)参考界面(6.转置矩阵对比可以去掉)

 
4)验收/测试用例

创建, 输入:4(行数) 4(列数) 5(非零元个数)

                   1,1,1) (2,3,2) (3,1,3) (3,4,5) (4,2,4)

检查非零元素个数是否小于等于行数乘列数;检查是否能拦截元素重复输入;检查是否能控制输入的非零元素的下标是递增的(即按照行序输入,先输入小的下标,再输入较大的下标)。

l 显示

屏幕上输出

             1  0  0  0

             0  0  2  0

             3  0  0  5

             0  4  0  0

l 转置

屏幕上输出

             1  0  3  0

             0  0  0  4

             0  2  0  0

             0  0  5  0

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h> 
#define form 12500
int num1,num2,num3,num4;
typedef struct
{
	int i,j;
	int e;
}triple;
typedef struct
{
	triple data[form+1];//三元组最大存储元素个数 
	int mu,nu,tu;//数组行数,列数,非零元素个数;
}TSMatrix;

void print(TSMatrix &M)
{
	if(M.mu==0&&M.nu==0&&M.tu==0) printf("该矩阵已被销毁\n");
	int p=1;
	int d;
	for(int a=0;a<M.mu;a++)
	{
		for(int b=0;b<M.nu;b++)
		{
			if((M.data[p].i-1)==a&&(M.data[p].j-1)==b)
			{
				d=M.data[p].e;
				p++;
			}
			else d=0;
			printf("%-4d",d);
		}
		printf("\n");
	}
} 
void TransposeSMatrix(TSMatrix M,TSMatrix &T) //求稀疏矩阵的一般算法 
{
	T.mu=M.mu; T.nu=M.nu; T.tu=M.tu;
	int p,q,col;
	if(T.tu)
	{
		q=1;
		for(col=1;col<=M.nu;col++)
		{
			for(p=1;p<=M.tu;p++)
			{
				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++;
				}	
			}	
		}	
	}
	print(T);
}
void FastTransposeSMatrix(TSMatrix M,TSMatrix &Q) //快速转置算法
{
	Q.mu=M.mu; Q.nu=M.nu; Q.tu=M.tu;
	int p,q,t,col,*num,*cpot;
	num=(int *)malloc((M.nu+1)*sizeof(int));	
	cpot=(int *)malloc((M.nu+1)*sizeof(int));
	if(Q.tu)
	{
		for(col=1;col<=M.nu;col++) num[col]=0;
		for(t=1;t<=M.tu;t++) num[M.data[t].j]++;
		cpot[1]=1;
		for(col=2;col<=M.nu;col++) cpot[col]=cpot[col-1]+num[col-1];
		for(p=1;p<=M.tu;p++)
		{
			col=M.data[p].j; q=cpot[col];
			Q.data[q].i=M.data[p].j;
			Q.data[q].j=M.data[p].i;
			Q.data[q].e=M.data[p].e;
			cpot[col]++;
		}
	}
	print(Q);
} 
int main()
{
	printf("*************************\n");
	printf("****1.创建矩阵    *******\n");
	printf("****2.销毁矩阵    *******\n");
	printf("****3.输出矩阵M   *******\n");
	printf("****4.转置矩阵    *******\n");
	printf("****5.快速转置矩阵*******\n");
	printf("****6.转置矩阵对比*******\n");
	printf("****7.退出        *******\n");
	printf("*************************\n");
	while(true)
	{
		TSMatrix M,T,Q;
		printf("请输入选择:");
		scanf("%d",&num1);
		if(num1==7) break; 
		switch(num1)
		{
			case 1:
			num2=0,num3=0,num4=0;
			while(true)
			{
				printf("请输入行数,列数,非零元素个数:");
				scanf("%d %d %d",&M.mu,&M.nu,&M.tu); 
				if(M.tu>(M.mu*M.nu)) 
				{
					printf("输入错误,非零元素个数大于总元素个数\n");
					continue;
				}
				else 
				{
					break;
				}
			} 
				for(int i=1;i<=M.tu;i++)
				{
					scanf("%d %d %d",&M.data[i].i,&M.data[i].j,&M.data[i].e);
					if(M.data[i].i>M.mu)
					{
						printf("输入行数大于设定行数之内,输入无效\n");
						i--;
					}
					if(M.data[i].j>M.nu||M.data[i].i<=0)
					{
						printf("输入列数不在设定列数之内,输入无效\n");
						i--; 
					}
					if(i>=2)
					{
						for(int j=1;j<i;j++)
						{
							if(M.data[i].i==M.data[j].i&&M.data[i].j<M.data[j].j)
							{
								num4=1;
								break; 
							}
						}
						if(num4==1)
						{
							printf("在行数相同时,输入列数递减,请重新输入\n");
							num4=0;
							i--;
						}
						for(int j=1;j<i;j++)
						{
							if(M.data[i].i==M.data[j].i&&M.data[i].j==M.data[j].j)
							{
								num2=1;
								break; 
							}
						}
						if(num2==1)
						{
							printf("输入重复,请重新输入\n");
							num2=0;
							i--;
						}
						for(int j=1;j<i;j++)
						{
							if(M.data[i].i<M.data[j].i)
							{
								num3=1;
								break;
							}
						}
						if(num3==1)
						{
							printf("输入行列小于上一个,请重新输入\n");
							num3=0;
							i--;
						}
					} 
					
				}	 
			break;	
			case 2:
				M.mu=0;
				M.nu=0;
				M.tu=0;
				printf("矩阵已经被销毁\n");	
				break;
			case 3: 
				print(M);
				break;
			case 4:
				TransposeSMatrix(M,T);
				break;
			case 5:
				FastTransposeSMatrix(M,Q);
				break;
		}
	}
	return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值