目录
一、数组的定义
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;
}
结构演示: