数组与线性表的差异
我们以前应该学习过数组,数组与线性表的区别与联系呢?
它们的相同之处:
(1)它们的相同之处,它们都是若干个相同数据类型的数据元素a0,a1,a2,…,an-1构成的有限序列
它们的不同之处:
(1)数组要求其元素占用一块地址连续的内存单元空间,而线性表无此要求
(2)线性表的元素是逻辑意义上不可再分的元素,而数组中的每个元素还可以是一个数组
(3)数组的操作主要是向某个下标的数组元素中存放数据和取某个下标的数组元素,这与线性表的插入和删除操作不同
数组的定义
数组的逻辑定义: n(n>1)维数组是一个向量,它的每个元素是n-1维数组,且具有相同的上限和下限。
n维数组的元素个数
设n维数组为:
A[c1..d1, c2..d2, … , cn..dn ]
其元素个数为:
- 数组逻辑上是线性结构的推广
- 数组是以线性表为元素的线性结构,而且元素的结构相同
- 数组可以看作是下标和值的偶对的集合
- 数组是一种逻辑结构
数组的操作 :数组一般不做插入和删除操作(效率较低)
对于数组的操作一般只有两类:
(1)给定一组下标,存取相应的数据元素
(2)给定一组下标,修改相应的数据元素的值
数组的顺序存储
(1)一维数组(n个元素)中任一元素ai的内存单元地址
LOC(ai)=LOC(a0)+i*k
(2)一个m行n列的二维数组
LOC(aij)=LOC(a00)+(i*n+j)*k
注意:C语言中数组元素采用行主序的存放方法,即行优先顺序。
顺序存储时按行序和列序的约定
以“行序为主序”的存储映象
二维数组中任一元素a[i][j] 的存储位置
LOC(i,j) = LOC(0,0) + (b2×i+j)×L
其中:LOC(0,0) 称为基地址或基址
设二维数组A[c1..d1][c2..d2] 其中c1、c2和d1、d2分别为二维数组A的下标的下界和上界,每个数组元素占L个存储单元,设第一个元素A[c1][c2]的存储位置为LOC(c1,c2),则该二维数组中任一元素A[i][j] ( c1≤i≤d1,c2≤j≤d2)的存储位置可由下式确定:
在C语言中,下标从零开始,即:A[0..d1][0..d2] ,则数组元素A[i][j]的存>储位置是 :
LOC(i,j)=LOC(0,0)+(i*(d2+1)+j)*L
n维数组的元素存储位置
N维数组中,数组元素存储位置的确定:
公式如下:
三维数组的表示方法
LOC(i,j,k) = LOC(l1,l2,l3)+
[ (i-l1) * (u2-l2) * (u3-l3) +( j-l2) * (u3-l3) + (k-l3) ]* L
若l1=l2=l3 = 0;
LOC(i,j,k) = LOC(0,0,0) + ( i * u2* u3 + j * u3 +k )*L
矩阵的压缩存储
压缩存储思想
当矩阵的阶数较高,而且矩阵中的一些元素有特殊的性质时,可以采用节省空间的存储办法(压缩存储)
特殊矩阵
值相同的元素或非零元素分布有一定的规律
(1) 对称矩阵
若n 阶方阵 A 中的元素满足下述性质:
aij=aji 1≤i , j≤n
则称A为n阶对称矩阵。
分析:
对于对称矩阵来说,n2个元素可以压缩到n(n+1)/2个空间中
以行序为主序将其下三角(包括对角线)中的元素
存储到一个向量B[n(n+1)/2]中:
对称矩阵特点:
向量B[k]和矩阵中的元素aij之间存在着一一对应关系:
下面按下标从从0开始讨论
下标变换公式
向量B[k]和矩阵中的元素aij之间的关系:由i和j推导k:
(2) 三角矩阵
什么是三角矩阵呢?
三角矩阵 :
下三角矩阵是指矩阵的上三角(不包括对角线)中的元素均为零或常数的n阶方阵
注意:下三角矩阵存储公式和对称矩阵存储主对角线以下元素的公式基本相同,只需额外再增加一个存储常数或零的存储空间即可
(3)对角矩阵
三对角矩阵:共3n-2个非零元素,存入B[3n-2]中,元素在一维数组B
中的下标k和元素在矩阵中的下标i和j的对应关系为:
k = 3(i-1)-1(主对角线左下角,即i=j+1)
k = 3(i-1) (主对角线上,即i=j)
k = 3(i-1)+1(主对角线上,即i=j-1)
由以上三式,得
k=2(i-1)+(j-1) (1 ≤ i,j ≤ n; 0 ≤ k ≤ 3n-1)
稀疏矩阵
非零元素少且分布无规律
稀疏因子:
假设 m 行 n 列的矩阵含 t 个非零元素,则
稀疏因子为δ = t/(m*n) <= 0.05
为什么使用稀疏矩阵?
以常规方法,即以二维数组表示高阶的稀疏矩阵时产生的问题:
(1)零值元素占了很大空间
(2)计算中进行了很多和零值的运算,遇除法,还需判别除数是否为零
解决问题的原则:
(1)尽可能少存或不存零值元素
(2)尽可能减少没有实际意义的运算
(3)操作方便。即:能尽可能快地找到与下标值(i,j)对应的元素,能尽可能快地找到同一行或同一列的非零值元
注意:压缩存储时,对零元素不分配存储空间,只存储稀疏矩阵中的非零元
顺序存储结构 — 三元组表
三元组顺序表
三元组类型
#define MAXSIZE 12500
typedef struct {
int i, j; //该非零元的行下标和列下标
ElemType e; // 该非零元的值
} Triple;
稀疏矩阵类型
typedef struct {
Triple data[MAXSIZE + 1];
int mu, nu, tu;
} TSMatrix;
链式存储结构 — 十字链表
十字链表中非零元结点的结构:
十字链表的结构类型
typedef struct OLNode {
int i , j;
ElemType e;
struct OLNode *down, *right;
}OLNode;*OLink;
typedef struct
{
OLink *rhead, *chead ; //行、列链表头指针
int mu, nu , tu ;
} CrossList;