稀疏矩阵的三元组表示----(算法详解)

目录

基本算法包括:(解释都在代码里)

1.创建

2.对三元组元素赋值

3.将三元组元素赋值给变量

4.输出三元组

5.转置(附加的有兴趣可以看看)


稀疏矩阵的概念:矩阵的非零元素相较零元素非常小时,这个矩阵就叫稀疏矩阵。

稀疏矩阵可以用三元组表示和十字链表表示

本文章介绍三元组表示

稀疏矩阵的三元组表示。

三元组表示就是,用三个变量来存储非零元素的信息。

三元组线性表按顺序存储结构存储。

三元组顺序表的数据类型声明如下:

cpp 复制代码
#include <stdio.h>
#define M 6
#define N 7
#define MaxSize  100         //矩阵中非零元素最多个数
typedef int ElemType;
typedef struct
{
	int r;					//行号
	int c;					//列号
	ElemType d;				//元素值
} TupNode;					//三元组定义
typedef struct 
{	
	int rows;				//行数
	int cols;				//列数
	int nums;				//非零元素个数
	TupNode data[MaxSize];
} TSMatrix;					//三元组顺序表

基本算法包括:(解释都在代码里)

1.创建

2.对三元组元素赋值

3.将三元组元素赋值给变量

4.输出三元组

5.转置(附加的有兴趣可以看看)

1.创建:

cpp 复制代码
void CreatMat(TSMatrix &t,ElemType A[M][N])  //从一个二维稀疏矩阵创建其三元组表示
{
	int i,j;
	t.rows=M;t.cols=N;t.nums=0;
	for (i=0;i<M;i++)
	{
		for (j=0;j<N;j++) 
			if (A[i][j]!=0) 	//只存储非零元素
			{
				t.data[t.nums].r=i;t.data[t.nums].c=j;
				t.data[t.nums].d=A[i][j];t.nums++;
			}
	}
}

2.对三元组元素赋值

先找行后找列

cpp 复制代码
bool Value(TSMatrix &t,ElemType x,int i,int j)  //三元组元素赋值
{
	int k=0,k1;
	if (i>=t.rows || j>=t.cols)
		return false;				//失败时返回false
	while (k<t.nums && i>t.data[k].r) k++;					//查找行
	while (k<t.nums && i==t.data[k].r && j>t.data[k].c) k++;//查找列
	if (t.data[k].r==i && t.data[k].c==j)	//存在这样的元素
		t.data[k].d=x;
	else									//不存在这样的元素时插入一个元素
	{	
		for (k1=t.nums-1;k1>=k;k1--)
		{
			t.data[k1+1].r=t.data[k1].r;
			t.data[k1+1].c=t.data[k1].c;
			t.data[k1+1].d=t.data[k1].d;
		}
		t.data[k].r=i;t.data[k].c=j;t.data[k].d=x;
		t.nums++;
	}
	return true;						//成功时返回true
}

3.将三元组元素赋值给变量

cpp 复制代码
bool Assign(TSMatrix t,ElemType &x,int i,int j)  //将指定位置的元素值赋给变量
{
	int k=0;
	if (i>=t.rows || j>=t.cols)
		return false;			//失败时返回false
	while (k<t.nums && i>t.data[k].r) k++;					//查找行
	while (k<t.nums && i==t.data[k].r && j>t.data[k].c) k++;//查找列
	if (t.data[k].r==i && t.data[k].c==j)
		x=t.data[k].d;
	else
		x=0;				//在三元组中没有找到表示是零元素
	return true;			//成功时返回true
}

4.输出三元组

cpp 复制代码
void DispMat(TSMatrix t)		//输出三元组
{
	int i;
	if (t.nums<=0)			//没有非零元素时返回
		return;
	printf("\t%d\t%d\t%d\n",t.rows,t.cols,t.nums);
	printf("\t------------------\n");
	for (i=0;i<t.nums;i++)
		printf("\t%d\t%d\t%d\n",t.data[i].r,t.data[i].c,t.data[i].d);
}

5.转置(附加的有兴趣可以看看)

cpp 复制代码
void TranTat(TSMatrix t,TSMatrix &tb)		//矩阵转置
{
	int p,q=0,v;					//q为tb.data的下标
	tb.rows=t.cols;tb.cols=t.rows;tb.nums=t.nums;
	if (t.nums!=0)					//当存在非零元素时执行转置
	{
		for (v=0;v<t.cols;v++)		//tb.data[q]中的记录以c域的次序排列
			for (p=0;p<t.nums;p++)	//p为t.data的下标
				if (t.data[p].c==v)
				{
					tb.data[q].r=t.data[p].c;
					tb.data[q].c=t.data[p].r;
					tb.data[q].d=t.data[p].d;
					q++;
				}
	}
}

总代码: c++

cpp 复制代码
//稀疏矩阵的三元组表示-算法
#include <stdio.h>
#define M 6
#define N 7
#define MaxSize  100         //矩阵中非零元素最多个数
typedef int ElemType;
typedef struct
{
	int r;					//行号
	int c;					//列号
	ElemType d;				//元素值
} TupNode;					//三元组定义
typedef struct 
{	
	int rows;				//行数
	int cols;				//列数
	int nums;				//非零元素个数
	TupNode data[MaxSize];
} TSMatrix;					//三元组顺序表

void CreatMat(TSMatrix &t,ElemType A[M][N])  //从一个二维稀疏矩阵创建其三元组表示
{
	int i,j;
	t.rows=M;t.cols=N;t.nums=0;
	for (i=0;i<M;i++)
	{
		for (j=0;j<N;j++) 
			if (A[i][j]!=0) 	//只存储非零元素
			{
				t.data[t.nums].r=i;t.data[t.nums].c=j;
				t.data[t.nums].d=A[i][j];t.nums++;
			}
	}
}
bool Value(TSMatrix &t,ElemType x,int i,int j)  //三元组元素赋值
{
	int k=0,k1;
	if (i>=t.rows || j>=t.cols)
		return false;				//失败时返回false
	while (k<t.nums && i>t.data[k].r) k++;					//查找行
	while (k<t.nums && i==t.data[k].r && j>t.data[k].c) k++;//查找列
	if (t.data[k].r==i && t.data[k].c==j)	//存在这样的元素
		t.data[k].d=x;
	else									//不存在这样的元素时插入一个元素
	{	
		for (k1=t.nums-1;k1>=k;k1--)
		{
			t.data[k1+1].r=t.data[k1].r;
			t.data[k1+1].c=t.data[k1].c;
			t.data[k1+1].d=t.data[k1].d;
		}
		t.data[k].r=i;t.data[k].c=j;t.data[k].d=x;
		t.nums++;
	}
	return true;						//成功时返回true
}

bool Assign(TSMatrix t,ElemType &x,int i,int j)  //将指定位置的元素值赋给变量
{
	int k=0;
	if (i>=t.rows || j>=t.cols)
		return false;			//失败时返回false
	while (k<t.nums && i>t.data[k].r) k++;					//查找行
	while (k<t.nums && i==t.data[k].r && j>t.data[k].c) k++;//查找列
	if (t.data[k].r==i && t.data[k].c==j)
		x=t.data[k].d;
	else
		x=0;				//在三元组中没有找到表示是零元素
	return true;			//成功时返回true
}
void DispMat(TSMatrix t)		//输出三元组
{
	int i;
	if (t.nums<=0)			//没有非零元素时返回
		return;
	printf("\t%d\t%d\t%d\n",t.rows,t.cols,t.nums);
	printf("\t------------------\n");
	for (i=0;i<t.nums;i++)
		printf("\t%d\t%d\t%d\n",t.data[i].r,t.data[i].c,t.data[i].d);
}
void TranTat(TSMatrix t,TSMatrix &tb)		//矩阵转置
{
	int p,q=0,v;					//q为tb.data的下标
	tb.rows=t.cols;tb.cols=t.rows;tb.nums=t.nums;
	if (t.nums!=0)					//当存在非零元素时执行转置
	{
		for (v=0;v<t.cols;v++)		//tb.data[q]中的记录以c域的次序排列
			for (p=0;p<t.nums;p++)	//p为t.data的下标
				if (t.data[p].c==v)
				{
					tb.data[q].r=t.data[p].c;
					tb.data[q].c=t.data[p].r;
					tb.data[q].d=t.data[p].d;
					q++;
				}
	}
}
int main()
{
	TSMatrix t,tb;
	int x,y=10;
	int A[6][7]={
		{0,0,1,0,0,0,0},
		{0,2,0,0,0,0,0},
		{3,0,0,0,0,0,0},
		{0,0,0,5,0,0,0},
		{0,0,0,0,6,0,0},
		{0,0,0,0,0,7,4}};
	CreatMat(t,A);
	//printf("b:\n"); DispMat(t);
	//if (Assign(t,x,2,5)==true)  //调用时返回true
	//	printf("Assign(t,x,2,5)=>x=%d\n",x);
	//else  //调用时返回false
	//	printf("Assign(t,x,2,5)=>参数错误\n");
	//Value(t,y,2,5);
	//printf("执行Value(t,10,2,5)\n");
	//if (Assign(t,x,2,5)==true)  //调用时返回true
	//	printf("Assign(t,x,2,5)=>x=%d\n",x);
	//else  //调用时返回false
	//	printf("Assign(t,x,2,5)=>参数错误\n");
	//printf("b:\n"); DispMat(t);
	TranTat(t,tb);
	printf("tb:\n"); DispMat(tb);
	return 1;
}

c总代码(需要自取)

cpp 复制代码
#define  _CRT_SECURE_NO_WARNINGS 1
#include <stdbool.h>
#include <stdio.h>
#include <string.h> 
#include <stdlib.h>
//三元组表示
typedef int ElemType;
#define MaxSize 100
#define M 6
#define N 7
typedef struct Tup
{
	int r;
	int c;
	ElemType d;
}TupNode;
typedef struct TS
{
	int rows;
	int cols;
	int nums;
	TupNode data[MaxSize];
}TsMatrix;
void CreateMat(TsMatrix* t, ElemType A[M][N])
{
	int i, j;
	t->rows = M; t->cols = N; t->nums = 0;
	for(i = 0;i<M;i++)
		for(j=0;j<N;j++)
			if (A[i][j] != 0)
			{
				t->data[t->nums].r = i; t->data[t->nums].c = j; t->data[t->nums].d = A[i][j]; t->nums++;
			}
}
bool Value(TsMatrix* t, ElemType x, int i, int j)
{
	if (i >= t->rows || j >= t->cols) return false;
	int k = 0;
	while (k<t->rows && i>t->data[k].r) k++;
	while (k<t->cols && i == t->data[k].r && j>t->data[k].c) k++;
	if (i == t->data[k].r && j == t->data[k].c) t->data[k].d = x;
	else {
		for (int k1 = t->nums - 1; k1 >= k; k1--)
		{
			t->data[k1 + 1].r = t->data[k1].r;
			t->data[k1 + 1].c = t->data[k1].c;
			t->data[k1 + 1].d = t->data[k1].d;
		}
		t->data[k].r = i; t->data[k].c = j; t->data[k].d = x;
		t->nums++;
	}
	return true;
}
void DispMat(TsMatrix* t)
{
	if (t->nums <= 0) return;
	printf("\t%d\t%d\t%d\n", t->rows, t->cols, t->nums);
	printf("\t--------------------------\n");
	for (int k = 0; k < t->nums; k++)
		printf("\t%d\t%d\t%d\n", t->data[k].r, t->data[k].c, t->data[k].d);
}
bool Assign(TsMatrix* t, ElemType* x, int i, int j)
{
	if (i >= t->rows || j >= t->cols) return false;
	int k = 0;
	while (k < t->nums && i>t->data[k].r) k++;
	while (k<t->nums && i == t->data[k].r && j>t->data[k].c)k++;
	if (t->data[k].r == i && t->data[k].c == j) *x = t->data[k].d;
	else x = 0;
	return true;
}
void TranTat(TsMatrix* t, TsMatrix* b)
{
	if (t->nums != 0)
	{
		b->rows = t->cols; b->cols = t->rows;
		b->nums = t->nums;
		int k1 = 0;
		for(int v = 0;v<t->cols;v++)
			for (int k = 0; k < t->nums; k++)
			{
				if (t->data[k].c == v)
				{
					b->data[k1].r = t->data[k].c;
					b->data[k1].c = t->data[k].r;
					b->data[k1].d = t->data[k].d;
					k1++;
				}
			}
	}

}

int main()
{
	ElemType A[6][7] = {
		{0,0,1,0,0,0,0},
		{0,2,0,0,0,0,0},
		{3,0,0,0,0,0,0},
		{0,0,0,5,0,0,0},
		{0,0,0,0,6,0,0},
		{0,0,0,0,0,7,4} };
	TsMatrix* t = (TsMatrix*)malloc(sizeof(TsMatrix));
	CreateMat(t, A);
	//Value(t, 7, 0, 4);
	ElemType e = 0;
	TsMatrix* b = (TsMatrix*)malloc(sizeof(TsMatrix));
	TranTat(t, b);
	/*Assign(t, &e, 1, 1);
	printf("%d", e);*/
	DispMat(b);
	return 0;
}

结语:

其实写博客不仅仅是为了教大家,同时这也有利于我巩固自己的知识点,和一个学习的总结,对文章有任何问题的还请指出,接受大家的批评,让我改进,如果大家有所收获的话还请不要吝啬你们的点赞和收藏,这可以激励我写出更加优秀的文章。

相关推荐
Lenyiin19 分钟前
02.06、回文链表
数据结构·leetcode·链表
爪哇学长22 分钟前
双指针算法详解:原理、应用场景及代码示例
java·数据结构·算法
爱摸鱼的孔乙己24 分钟前
【数据结构】链表(leetcode)
c语言·数据结构·c++·链表·csdn
Dola_Pan26 分钟前
C语言:数组转换指针的时机
c语言·开发语言·算法
繁依Fanyi38 分钟前
简易安卓句分器实现
java·服务器·开发语言·算法·eclipse
烦躁的大鼻嘎1 小时前
模拟算法实例讲解:从理论到实践的编程之旅
数据结构·c++·算法·leetcode
C++忠实粉丝1 小时前
计算机网络socket编程(4)_TCP socket API 详解
网络·数据结构·c++·网络协议·tcp/ip·计算机网络·算法
用户37791362947552 小时前
【循环神经网络】只会Python,也能让AI写出周杰伦风格的歌词
人工智能·算法
福大大架构师每日一题2 小时前
文心一言 VS 讯飞星火 VS chatgpt (396)-- 算法导论25.2 1题
算法·文心一言
EterNity_TiMe_2 小时前
【论文复现】(CLIP)文本也能和图像配对
python·学习·算法·性能优化·数据分析·clip