数组与稀疏矩阵

目录

一、数组的定义

1、一维数组的定义

2、二维数组的定义

二、数组的存储结构

1、数组存储方式

2、二维数组的存储方式

(1)按行优先存储方式

 (2)按列优先存储方式

三、矩阵

1、矩阵的定义

2、特殊矩阵的定义

3、特殊矩阵的压缩存储

四、稀疏矩阵

1、稀疏矩阵的定义

2、稀疏矩阵的存储方式

3、稀疏矩阵的三元组存储方式

 五、例题讲解


一、数组的定义

1、一维数组的定义

由n(n>1)个相同性质数据元素所构成的有限序列。如:

其本身也是一个线性表。

2、二维数组的定义

用于存储数组的数组,称为二维数组。由于一维数组是一个线性表,故二维数组也可以看成一个线性表,其每一个数据元素皆是一个线性表。类似于数学上矩阵。(关于其他数组的基本介绍可见数组的详细介绍_m0_50708613的博客-CSDN博客

如图所示:二维数组S以m行n列的矩阵

 其采用二元组形式化描述为:

二、数组的存储结构

1、数组存储方式

一般数组采用顺序存储结构存储。这与内存的存储单元是一维结构有着极大关系。

2、二维数组的存储方式

二维数组的存储次序有按行优先和按列优先两种方式。

(1)按行优先存储方式

设每个元素占有k个存储单元,用表示某个元素的存储地址。

 在C语言中数组下标是从0开始

 (2)按列优先存储方式

设每个元素占有k个存储单元,用表示某个元素的存储地址。

三、矩阵

1、矩阵的定义

矩阵(Matrix)是一个又m行n列组成数表。

2、特殊矩阵的定义

特殊矩阵一般是指非零元素或零元素的分布有一定规律的矩阵,也称为方阵。有对称矩阵、正交矩阵、对角矩阵和零矩阵,等。

3、特殊矩阵的压缩存储

(1)对称矩阵

a:对称矩阵的定义

一个n阶方阵中的元素满足,称为n阶对称矩阵。

b:对称矩阵的存储

根据对称矩阵的特性,对称矩阵沿着主对角线对称,故存储时可只存储上三角线或下三角线部分元素,也将原本有存储的n^2个元素压缩存储到了n(n-1)/2个元素的存储空间。(类似于九九乘法表的分布)

四、稀疏矩阵

1、稀疏矩阵的定义

当矩阵中非零元素远小于矩阵总元素个数的矩阵,称为稀疏矩阵。

2、稀疏矩阵的存储方式

三元组和十字链表两种存储方式。稀疏矩阵的的压缩存储方式值仅仅存储非零元素。

3、稀疏矩阵的三元组存储方式

a:将稀疏矩阵中每一个非零元素采用一个三元组

唯一确定,故最终形成一个三元组线性表,因此其存储方式为顺序存储结构存储。如图所示:

 b:代码实现

#include <stdio.h>
#include <malloc.h>
#include <string.h>
typedef int ElemType;
#define M 4
#define N 5

#define MaxSize 200
//结构声明
typedef struct
{
	int r;       //行号
	int c;       //列号
	ElemType d;
}SpMatrix;

typedef struct
{
	int rows;    //行数
	int cols;    //列数
	int nums;    //非零元素个数
	SpMatrix data[MaxSize];
}TriPle;               //三元组顺序表定义

//创建其三元组
void CreatMat(TriPle &t,ElemType S[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(S[i][j]!=0)
			{
				t.data[t.nums].r=i;
				t.data[t.nums].c=j;
				t.data[t.nums].d=S[i][j];
				t.nums++;
			}
	}
}

//三元组元素赋值

int Value(TriPle &t,ElemType x,int i,int j)
{
	int k=0,k1;
	if(i>=t.rows || j>=t.cols)
		return 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(k<t.nums && 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 1;
}

//将指定位置的元素值赋给变量

int Assign(TriPle t,ElemType &x,int i,int j)
{
	int k=0;
	if(i>=t.rows || j>=t.cols)
		return 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(k<t.nums && t.data[k].r==i && t.data[k].c==j)
		x=t.data[k].d;
	else
		x=0;                                                //在三元组中没有找到表示是零元素
	return 1;
}

//输出三元组
void DispMat(TriPle 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 main()
{
	TriPle t;
	ElemType x;
	ElemType S[M][N]={{0,0,4,0,2},{6,0,0,0,0},{0,5,0,0,0},{0,0,0,9,0}};
	CreatMat(t,S);
	printf("三元组t表示:\n");
	DispMat(t);
	printf("执行S[2][1]=6\n");
	Value(t,6,2,1);
	printf("三元组t表示:\n");
	DispMat(t);
	printf("求x=S[2][1]\n");
	Assign(t,x,2,1);
	printf("x=%d\n",x);
}

 c:结果演示

 五、例题讲解

实现一个m*n的整型数组S的装置运算。

代码实现:

#include <stdio.h>

int main()
{
	int S[4][4]={{10,89,23,56},{38,53,25,33},{76,67,45,51},{90,104,19,48}};
	int i,j,temp;
	printf("原始数组矩阵:\n");
		for(i=0;i<4;++i)
	{
		for(j=0;j<4;++j)
		{
			printf("%d ",S[i][j]);
		}
			printf("\n");
	}
	for(i=0;i<4;++i)
	{
		for(j=0;j<4;++j)
		{
			if(j>i)
			{
			temp=S[i][j];
			S[i][j]=S[j][i];
			S[j][i]=temp;
			}
		}
	}
	printf("转置后的矩阵:\n");
		for(i=0;i<4;++i)
	{
		for(j=0;j<4;++j)
		{
			printf("%d ",S[i][j]);
		}
			printf("\n");
	}
		return 0;
	
	}

结构演示:

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

斯择微韵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值