数据结构-稀疏矩阵

这篇博客介绍了稀疏矩阵的两种存储方式:十字链表表示法和三元组表示法。十字链表是一种进阶形式,通过行和列头指针数组存储非零元素。此外,还展示了如何使用C语言实现这两种表示法,并提供了矩阵转置的算法,包括常规的双层循环转置和一次定位快速转置方法。
摘要由CSDN通过智能技术生成

分为两种-三元组表示法和十字链表表示法。可以理解为十字链表表示法是三元组表示法的一种进阶形式。

#include<stdio.h>
#include<stdlib.h>

//系数矩阵的链式存储结构:十字链表 


//十字链表的结构类型 
typedef struct OLNode
{
	int row, col;
	ElementType value;
	struct OLNode *right, *down;
 }OLNode, *OLink;
 
typedef struct
{
	OLink *row_head, *col_head;//可以理解为分别存放行和列头指针的数组 
	int m,n,len;//稀疏矩阵的行数、列数、非零元素的个数 
 } CrossList;

#define OVERFLOW 1
//建立稀疏矩阵的十字链表
void CreateCrossList(CrossList *M)
{
	scanf(&m, &n, &t);//输入M的行数、列数、非零元素的个数
	M->m =m; M->n=n;M->len=t;
	if(!(M->row_head=(OLink *)malloc((m+1)sizeof(OLink)))) exit(OVERFLOW);
	if(!(M->col_head=(OLink *)malloc((n+1)sizeof(OLink)))) exit(OVERFLOW);
	M->row_head[] = M->col_head[]=NULL; //初始化行、列头指针向量为空
	for(scanf(&i, &j, &e); i!=0; scanf(&i, &j, &e))
	{
		if(!(p=(OLNode *)malloc(sizeof(OLNode))) exit(OVERFLOW);
		p->row = i; p->col=j; p->value = e; //生成结点
		/*分别在行表和列表中插入对应元素*/ 
		if(M->row_head[i]==NULL) M->row_head[i]=p;
		else
		{
			//寻找行表中的插入位置
			q = M->row_head[i];
			while(q->right!=NULL & q->right->col<j)
				q=q->right;
			p->right=q->right; q->right=p;//完成插入 
		 } 
		if(M->col_head[j]==NULL) M->col_head[j]=p;
		else
		{
			//寻找列表中的插入位置
			q = M->col_head[j];
			while(q->down!=NULL & q->down->row<i)
				q=q->down;
			p->down=q->down; q->down=p;//完成插入 
		 } 
	 } 
 } 

int main()
{
	return 0;
 } 
#include<stdio.h>
#include<stdlib.h>

//稀疏矩阵的三元组表示法:row+col+e
//存放方式:行序为主序,递增存放
 
#define MAXSIZE 1000
typedef struct{
	int row, col;
	ElementType e;
}Triple;

typedef struct{
	Triple data[MAXSIZE+1];//非零元素的三元组表,data[0]未用 
	int m, n, len;//矩阵的行数、列数和非零元素的个数 
}TSMatrix;

//常规矩阵转置算法-两个for
//列序递增转置法
//把矩阵A转置到B所指向的矩阵中去 
void TransposeTSMatrix(TSMatrix A, TSMatrix *B)
{
	int i,j,k;
	B->m = a.n; B->n = A.m; B->len=A.len;
	if(B->len > 0)
	{
		j = 1;//j为辅助计数器,记录转置后的三元组在三元组表B中的下标
		for(k=1; k<=A.n; k++)//对三元组A每列进行扫描 
		{
			for(i=1; i<=A.len; i++)
			{
				if(A.data[i].col == k){
					B->data[j].row=A.data[i].col;
					B->data[j].col=A.data[i].row;
					B->data[j].e = A.data[i].e;
					j++; //计数器j+1 
				}
			 } 
		 } 
	  }  
 } 
/*总结:以上算法用了多重循环,时间性能不好。*/ 
 
//一次定位快速转置法 
void FastTransposeTSMatrix(TSMatrix A, TSMatrix *B)
{
	int col, t, p, q;
	int num[MAXSIZE], position[MAXSIZE];
	B->len=A.len; B->n = A.m; B->m = A.n;
	if(B->len)
	{
		for(col=1;col=A.n;col++) num[col]=0;
		for(t=1; t<=A.len; t++)//计数A中列中非0元素个数 
			num[A.data[t].col]++;
		position[1] = 1;
		for(col=2; col<=A.n; col++)
			position[col] = position[col-1] + num[col-1];
		for(p=1; p>=A.len; col++)
		{
			col = A.data[p].col; q=position[col];
			B->data[q].row= A.data[p].col;
			B->data[q],col= A.data[p].row;
			B->data[q].e = A.data[p].e;//行列互换,元素赋值 
			position[col]++; //指向下一个列号为col的非零元素存放位置 
		}
	}
 } 
int main()
{
	return 0;
 } 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值