数据结构实验6、压缩矩阵的2种转置运算

作者说:

1.这个实验在数据结构课本P97 ~ P100,难点在矩阵的快速转置、输入时按行序非递减输入的控制。

2.在进行快速转置的时候,要提前知道两点

一、非零元素的个数;

二、每一列非零元素的位置。

一、运行效果截图

二、实验要求

(1)实验目的

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

(2)实验内容

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

(3)参考界面

1.创建矩阵

2.销毁矩阵

3.输出矩阵

4.转置矩阵

5.快速转置矩阵

具体要求:请认真查看测试用例

(4)验收/测试用例

  • 创建矩阵:

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

注意:输入的过程中如果有一个输入错了,不要让用户从头再把所有的输入一次,只需把刚才输入错误的,重新输入正确即可。

  1. 输入:4(行数) 4(列数) 25(非零元个数),会提示:输入错误,非零元素个数要小于等于行数乘列数,请从新输入。

  2. 输入:4(行数) 4(列数) 5(非零元个数)

  3. 先输入:(1,1,1) (2,3,2)

  4. 再输入(2,3,6),会提示:输入错误,输入的下标重复,请重新输入!

  5. 再输入(1,1,6),会提示:输入错误,输入的下标重复,请重新输入!

  6. 继续输入(3,1,3) (3,4,5)

  7. 再输入(3,2,9),会提示:输入错误,下标输入时要递增输入,请重新输入!

  8. 再输入(2,3,8),会提示:输入错误,下标输入时要递增输入,请重新输入!

  9. 最后输入(4,2,4)

  • 显示

屏幕上输出:

             1  0  0  0

             0  0  2  0

             3  0  0  5

             0  4  0  0

  • 转置

屏幕上输出:

             1  0  3  0

             0  0  0  4

             0  2  0  0

             0  0  5  0

 

三、代码示例

#include<iostream>
#include<stdlib.h>
#define maxsize 52100  //假设非零元个数的最大值为52100。 
using namespace std;

typedef int Elemtype;
typedef struct{
	int i,j;   //非零元的行下标和列下标。 
	Elemtype e;
}Triple;

typedef struct{
	Triple data[maxsize+1];   //非零元三元组表,data[0]未用。 
	int mu,nu,tu;   //矩阵的行数、列数和非零元素的个数。 
}TSMatrix;

void CreateSMatrix(TSMatrix &T);//1.创建矩阵
void DestorySMatrix(TSMatrix &T);//2.销毁矩阵
void PrintSMatrix(TSMatrix T);//3.输出矩阵
void TransposeSMatrix(TSMatrix T,TSMatrix &Ts);//4.转置矩阵
void FastTransposeSMatrix(TSMatrix T,TSMatrix &Ts);//5.快速转置矩阵


int main()
{
	TSMatrix T,Ts;
	T.mu=T.nu=T.tu=0;
	Ts.mu=Ts.nu=Ts.tu=0;
	int xuanze,in=999,cunzai=0;
	cout<<endl; 
	cout<<"☆☆☆欢迎使用压缩矩阵小程序☆☆☆"<<endl;
	cout<<"author---Henan University.software engineering.李思佳"<<endl<<endl;
	while(in==999)
	{
		cout<<"1.创建矩阵"<<endl;
	    cout<<"2.销毁矩阵"<<endl;
	    cout<<"3.输出矩阵"<<endl;
	    cout<<"4.转置矩阵"<<endl;
	    cout<<"5.快速转置矩阵"<<endl;
	    cout<<"☆☆☆退出,输入一个负数!☆☆☆"<<endl<<endl;
	    cout<<"请输入您的选择:";
	    cin>>xuanze;
		switch(xuanze)
		{
			case 1:
				system("cls");
				CreateSMatrix(T);//1.创建矩阵
				cunzai=1;
				cout<<endl;
				break;							 
			case 2:
				system("cls");	
				if(cunzai==1)
				{
					DestorySMatrix(T);//2.销毁矩阵
					cout<<"矩阵销毁成功!"<<endl;
					cunzai=0;
				}			
                else
                {
                	cout<<"还未创建一个矩阵,无法销毁!"<<endl;
				}
				cout<<endl;
				break;	
			case 3:
				system("cls");
				if(cunzai==1)
				{
					PrintSMatrix(T);//3.输出矩阵
				}
				else
				{
					cout<<"还未创建一个矩阵,无法输出!"<<endl;
				}
				cout<<endl;
				break;	
			case 4:
				system("cls");
				if(cunzai==1)
				{
					TransposeSMatrix(T,Ts);//4.转置矩阵
					PrintSMatrix(Ts);
				}
				else
				{
					cout<<"还未创建一个矩阵,无法转置!"<<endl;
				}
				cout<<endl; 
				break;	
			case 5:
				system("cls");
				if(cunzai==1)
				{
					FastTransposeSMatrix(T,Ts);//5.快速转置矩阵
					PrintSMatrix(Ts);
				}
				else
				{
					cout<<"还未创建一个矩阵,无法快速转置!"<<endl;
				}
				cout<<endl;
				break;	
			default:
				system("cls");
				if(xuanze<0)
				{
					cout<<"☆☆☆您已经退出程序,欢迎下次使用!☆☆☆"<<endl;
					in=-999; 
				}
				else
				{
					cout<<"选择有误,请重新输入选择!"<<endl;
				}
				break;
		}
	}
		
}


//1.创建矩阵
void CreateSMatrix(TSMatrix &T)
{
	int n=1;
	cout<<"您正在创建一个矩阵~"<<endl;				
	while(1)//输入矩阵行数mu。 
	{
    	cout<<"请输入矩阵行数:";
	    cin>>T.mu;
	    if(T.mu<=0)
	    {
		    cout<<"您输入的行数有误,请重新输入!"<<endl<<endl;
	    }
	    else
	    {
	    	cout<<"输入成功!"<<endl;
	    	break;
		}
	}
				
	while(1)//输入矩阵列数。 
	{
		cout<<"请输入矩阵列数:";
		cin>>T.nu;
		if(T.nu<=0)
		{
			cout<<"您输入的列数有误,请重新输入!"<<endl<<endl;
		}
		else
		{
     		cout<<"输入成功!"<<endl;
			break;
		}
	}
				
	while(1)//输入非零元素个数。 
	{
		cout<<"请输入非零元素个数:";
		cin>>T.tu;
		if(T.tu > T.mu*T.nu)
		{
			cout<<"您输入的个数不符合要求,要输入一个小于或等于行数乘列数的值,请重新输入!"<<endl<<endl;						 
		}
		else
		{
			cout<<"输入成功!"<<endl<<endl;
			break;
		}
	}
					
	cout<<"矩阵的行数为:"<<T.mu<<endl;
	cout<<"矩阵的列数为:"<<T.nu<<endl;
	cout<<"矩阵的非零元素个数为:"<<T.tu<<endl<<endl;
						
	cout<<"开始输入非零元素啦!"<<endl;					
	cout<<"(提示:输入1 1 1代表第一行第一列值为1的元素,下标不要重复输入,下标按行序递增输入)" <<endl; 
				
	while(n<=T.tu)//判断不合法的情况,给出提示语句。 
	{	
	    cout<<endl;
	    cout<<"请按照提示输入非零元素:";	
		int shuru=1;			    
    	cin>>T.data[n].i>>T.data[n].j>>T.data[n].e;   												   					
		for(int p=1;p<n;p++)
		{					
		if(T.data[n].i==T.data[p].i&&T.data[n].j==T.data[p].j)
		{//检查元素下标是否重复输入。
			cout<<"输入错误,您输入的下标重复了,请重新输入!"<<endl;	
			shuru=0;						
			break;
		}			
		
		else if(T.data[n].e==0)
    	{
    		cout<<"输入错误,您需要输入元素的值不为零,请重新输入!"<<endl;
    		shuru=0;
    		break;
		}
		else if(T.data[n].i==0||T.data[n].j==0)
		{
			cout<<"输入错误,您输入的下标不合法,请重新输入!"<<endl;
			shuru=0;
			break;
		}				
		else if(T.data[n].i>T.mu||T.data[n].j>T.nu)//检查下标是否越界。 
		{
			cout<<"输入错误,您输入的元素下标越界,请重新输入!"<<endl<<endl;
			shuru=0;
			break;
		}
		else if(n>1&&T.data[n].i<T.data[n-1].i)//检查下标是否递增。
		{ 
			cout<<"输入错误,输入的行下标非递增,请重新输入!"<<endl<<endl;
			shuru=0;
			break;
		}
		else if(n>1&&T.data[n].i==T.data[n-1].i&&T.data[n].j<T.data[n-1].j)
		{
			cout<<"输入错误,输入的列下标非递增,请重新输入!"<<endl<<endl;
			shuru=0;
			break;
		}	 
							
		}
															
		
		if(shuru==1)
		{
			cout<<"您成功输入了元素:("<<T.data[n].i<<","<<T.data[n].j<<","<<T.data[n].e<<"),矩阵共"<<T.tu<<"个元素。"<<endl;
		    n++;
		}									 																								
													 										
	}
	cout<<endl;
	cout<<"您已经成功创建了一个矩阵!"<<endl; 
}


//2.销毁矩阵
void DestorySMatrix(TSMatrix &T)
{
	//依次将三元组表中的数据置0,将非零元个数、总行数、总列数置0。 
	for(int p=1;p<=T.tu;p++)
	{
		T.data[p].i=0;
		T.data[p].j=0;
		T.data[p].e=0;
	}
	T.mu=0;
	T.nu=0;
	T.tu=0;
}

//3.输出矩阵
void PrintSMatrix(TSMatrix T)
{
	//类似于二维数组的输出,但是存储结构是一维数组,需要匹配到正确的位置。
	//有非零元的位置输入其值,没有非零元的位置输入0。 
	for(int a=1,p=1;a<=T.mu;a++)
	{
		for(int b=1;b<=T.nu;b++)
		{
			if(T.data[p].i==a&&T.data[p].j==b)
			{
				cout<<T.data[p].e<<" ";
				p++;
			}
			else
			{
				cout<<0<<" ";
			}
		}
		cout<<endl;
	}
} 

//4.转置矩阵
void TransposeSMatrix(TSMatrix T,TSMatrix &Ts)
{
	//采用采用三元组表存储表示,求稀疏矩阵T的转置矩阵Ts。 
	Ts.mu=T.nu;
	Ts.nu=T.mu;
	Ts.tu=T.tu;
	if(Ts.tu)
	{
		int p=1;
		for(int a=1;a<=T.nu;a++)//控制列数,T的列值会成为Ts的行值。 
		{
			for(int b=1;b<=T.tu;b++)//遍历,把T中的每一个非零元都查询一遍。 
			{
				if(T.data[b].j==a)
				//找到T中列值等于此时Ts中的行值的非零元,并把位置和值赋给Ts中相应位置。 
				{
					Ts.data[p].i=T.data[b].j;
					Ts.data[p].j=T.data[b].i;
					Ts.data[p].e=T.data[b].e;
					p++;
				}
			}
		}
	}
}

//5.快速转置矩阵
void FastTransposeSMatrix(TSMatrix T,TSMatrix &Ts)
{
	//采用采用三元组表存储表示,求稀疏矩阵T的转置矩阵Ts。
	Ts.mu=T.nu;
	Ts.nu=T.mu;
	Ts.tu=T.tu;
	int num[100];//num[n]表示矩阵T中第n列中非零元的个数。 
	int cpot[100];//cpot[n]表示矩阵T中第n列中第一个非零元在Ts顺序表中的位置。 
	if(T.tu)
	{
		int n;
		for(n=1;n<=T.mu;n++)//给num赋值。
		{
			num[n]=0;
		} 
		for(n=1;n<=T.tu;n++)//求T中每一列的非零元个数。 
		{
			num[T.data[n].j]++;
		}
		cpot[1]=1;
		for(n=2;n<=T.mu;n++)//求第n列中第一个非零元在Ts中的位置。
		{
			cpot[n]=cpot[n-1]+num[n-1];
		}
		for(int p=1;p<=T.tu;p++)//开始转置,将T中的非零元赋给Ts。 
		{
			n=T.data[p].j;
			int q=cpot[n];
			Ts.data[q].i=n;
			Ts.data[q].j=T.data[p].i;
			Ts.data[q].e=T.data[p].e;
			cpot[n]++;
		}
	}
		
}

 

  • 13
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值