数据结构稀疏矩阵的实现及转置

本文深入探讨了如何使用三元组顺序表实现矩阵的线性存储,并详细解释了矩阵转置的算法过程。通过实际代码示例,展示了如何创建矩阵、存储非零元素并进行矩阵转置,最终实现矩阵的可视化输出。文章旨在帮助读者掌握数据结构与算法中关于矩阵操作的核心概念。

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

     昨天在机房没有做出来,我想了很久,都不知道原因。在机房时就是不明白那些Triple和TSMatrix结构之间的联系。不知道如何进行数据输入和输出。

      且我一直在思考如果创建矩阵成功,又如何将其可视化的输出呢,就像我们看数学课本上的矩阵那样。今天晚上才明白过了。三元组顺序表实际是将看似非线性的矩阵实现了线性化的存储。不过现在看来我真正理解那个矩阵转置算法还需花时间。数据结构与算法的这个矩阵利用三元组顺序表实现线性存储让我明白了计算机是如此的傻瓜和伟大。记得去年这个时候我还在一直困惑着“计算机如何利用0和1实现存储图像、音乐、视频等,这完全不可能吧”,现在我学了数据结构与算法的一点皮毛,让我彻底相信计算机仅仅利用0和1是可以实现这些的,且完全有可能做更多的事情。


下面是利用三元组顺序表创建矩阵、存储和进行矩阵转置的代码:

#include<iostream>
#include<iomanip>
using namespace std;
#define MAXSIZE 12500
typedef struct
{
	int i,j;//该非零元的行下标和列下标
	int e;

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

}TSMatrix;
void initTS(TSMatrix &X)
{
	cout<<"请输入你要创建的矩阵的行数列数和非零元个数"<<endl;
	cin>>X.mu>>X.nu>>X.tu;
	cout<<"您要创建的矩阵的行数、列数、和非零元个数分别为:"
		<<X.mu<<" "<<X.nu<<" "<<X.tu<<endl;
	int p;
		cout<<"现在开始输入矩阵的元素了!请在输完一个元素后回车(*^__^*) \a"<<endl;
	for(p=1;p<=X.tu;p++)//构造循环,直到输完所有非零元素结束
	{
		cout<<"请输入第 "<<p<<"个非零元素的行数:";
		cin>>X.data[p].i;
		cout<<"请输入列数:";
		cin>>X.data[p].j;
			cout<<"请输入具体的数值:";
			cin>>X.data[p].e;
		cout<<endl;
	
	}


}
void print(TSMatrix X)
{
	cout<<"现在的矩阵为:"<<endl;
	for(int k=1;k<=X.tu;k++)
	{
		cout<<"矩阵的行数  "<<"矩阵的列数  "<<"内容"<<endl;
		cout<<setw(8)<<X.data[k].i<<setw(8)<<X.data[k].j<<setw(8)<<X.data[k].e<<endl;
	}


}
void TransposeSM(TSMatrix X,TSMatrix &T)
{
	cout<<"正在对矩阵进行转置!"<<endl;
	T.mu=X.nu;
	T.nu=X.mu;
	T.tu=X.tu;
	if(T.tu)
	{
		int q=1;
		for(int col=1;col<=X.nu;++col)//注意不忘了等于
			for(int p=1;p<=X.tu;++p)
				if(X.data[p].j==col)
				{
					T.data[q].i=X.data[p].j;
					T.data[q].j=X.data[p].i;
					T.data[q].e=X.data[p].e;
					++q;
				
				
				}
	
	
	}

}
int main()
{
	TSMatrix X,T;
	initTS(X);
	print(X);
	TransposeSM(X,T);
	cout<<"矩阵X的转置矩阵为:"<<endl;
	print(T);

	

return 0;
}




网上 收集的代码参考:

//.......SparseMatrix.h

#include<iostream.h>
#include<stdio.h>
#define MAXSIZE 12500
typedef struct{
 int i,j;//非0元素的行下标,列下标
 int e;//非0元素的值
}Triple;
typedef struct{
 Triple data[MAXSIZE];
 int mu,nu,tu;//稀疏矩阵的行数,列数和非0元素个数
}TSMatrix;
//--------------------------------------------------------------
//创建稀疏矩阵
//--------------------------------------------------------------
void CreateSMatrix(TSMatrix &M){
 int num;//非0元素的个数
 int m;//遍历矩阵的字符
 int Rnum,Cnum;//稀疏矩阵的行数,列数
 int row,col,a;//非0元素的行下标,列下标,值
 cout<<"请输入系数矩阵非0元素的个数,num= ";
 cin>>num;
 cout<<"\n\n------------------------------\n";
 M.tu =num;
 cout<<"请输入稀疏矩阵的行数,Rnum= ";
 cin>>Rnum;
 M.mu =Rnum;
 cout<<"\n------------------------------\n";
 cout<<"请输入稀疏矩阵的列数,Cnum= ";
 cin>>Cnum;
 M.nu =Cnum;
 cout<<"\n------------------------------\n";
 for(m=0;m<num;m++)
 {
  cout<<"第"<<m+1<<"个非0元素是:\n";
  cout<<"行数 ";
  cin>>row;
  cout<<"\n------------------------------\n";
  cout<<"列数 ";
  cin>>col;
  cout<<"\n------------------------------\n";
  cout<<"值 ";
  cin>>a;
  cout<<"\n------------------------------\n\n";
  M.data[m].i =row;
  M.data[m].j =col;
  M.data[m].e =a;
 }
// M.tu =num;
}
//--------------------------------------------------------------
//输出稀疏矩阵
//--------------------------------------------------------------
void PrintSMatrix(TSMatrix M){
 int n;
 cout<<"稀疏矩阵是: \n";
 cout<<"i  "<<"j  "<<"e  \n";
 for(n=0;n<M.tu;n++)
 {
  cout<<M.data[n].i<<"  "<<M.data[n].j <<"  "<<M.data[n].e<<endl;
 }
}
//--------------------------------------------------------------
//稀疏矩阵转置
//--------------------------------------------------------------
bool TransposeSMatrix(TSMatrix M,TSMatrix &T){
 int q;//矩阵T的数组下标
 int p;//遍历矩阵M的字符
 int col;//矩阵M的列数
 T.mu =M.nu ;
 T.nu =M.mu ;
 T.tu =M.tu ;
 if(T.tu )
 {
  q=0;
  for(col=1;col<=M.nu ;col++)
   for(p=0;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++;
    }
 }
 return true;
 return false;
}
//----------------------------------------------------------------------
//稀疏矩阵转置—2
//----------------------------------------------------------------------


///.....main.cpp

//#include"SparseMatrix.h"
void main(){
 TSMatrix M,T;
 CreateSMatrix(M);
 PrintSMatrix(M);
 cout<<"矩阵M转置后:";
 cout<<"\n\n----------------------------\n\n";
 if(TransposeSMatrix(M,T))
  PrintSMatrix(T);
 getchar();
}


### 关于稀疏矩阵快速转置数据结构算法 #### 稀疏矩阵特点 稀疏矩阵是指大部分元素为零的矩阵。为了节省空间并提高运算效率,通常采用特殊的存储方式来表示这些矩阵。一种常见的方法是通过三元组表存储非零元素的位置及其值。 #### 快速转置原理 对于一个大小为 \(m \times n\) 的稀疏矩阵 A ,其快速转置的核心在于减少不必要的遍历次数。传统的方法会逐个访问原矩阵中的每一个位置,而快速转置则只关注那些实际存在的非零项,并且能够一次性定位到它们应该被放置的新位置上[^1]。 #### 时间复杂度分析 该过程主要包括三个阶段: - **统计各列中非零元素的数量**:此步需要扫描整个原始列表一次,时间开销为 \(O(t)\),这里 \(t\) 表示非零元素数目。 - **确定每一行第一个非零元素所在新数组里的索引**:这一步涉及到了对所有可能的目标行号(即原来的列编号)做预处理,所以耗时大约为 \(O(n)\)[^3]。 - **完成最终转换工作**:最后再走一遍所有的非零条目,按照之前算好的映射关系填入新的二维表格里去,同样花费 \(O(t)\) 的代价。 综上所述,整体性能达到了最优状态下的线性级别——\(O(n + t)\);当非零比例较高接近满阵情况时,则退化成平方阶别的表现形式\[O(m * n)]\). #### C++ 实现案例 下面给出一段基于上述理论框架的具体编程实践代码片段,在这段程序里面实现了如何高效地把给定的一个稀疏矩阵对象A转变为它的转置版本B: ```cpp #include <vector> using namespace std; struct Triple { int row, col; double value; }; void FastTranspose(const vector<Triple>& A, vector<Triple>& B){ int num_rows_A = /* 获取A的最大行数 */; int num_cols_A = /* 获取A的最大列数 */; // 记录每列有多少个非0元素 vector<int> count(num_cols_A); for(auto& triple : A){ ++count[triple.col]; } // 计算每个col的第一个non-zero element在result中的起始index vector<int> start_pos(num_cols_A); for(int i=1; i<num_cols_A; ++i){ start_pos[i]=start_pos[i-1]+count[i-1]; } // 构建结果集 B.resize(A.size()); for(auto &a:A){ int pos=start_pos[a.col]++; B[pos].row=a.col; B[pos].col=a.row; B[pos].value=a.value; } } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值