🌟 嗨,我是Lethehong!🌟
🌍 立志在坚不欲说,成功在久不在速🌍
🚀 欢迎关注:👍点赞⬆️留言收藏🚀
🍀欢迎使用:小智初学计算机网页AI🍀
目录
一、数组的基本概念
二、数组的表示方法
(1)一维数组


#define MAX_ROW_INDEX 10
#define MAX_COL_INDEX
10
typedef struct {
EnterType item[MAX_ROW_INDEX][MAX_COL_INDEX] ;
} ARRAY;
(2)二维数组

- 第 i 行数据元素的起始地址为:(i-1) ×U2×d + L1
- 数组元素 A[i,j]的地址为:Loc(A[i,j]) = L1 + (i-1)×U2 ×d + (j-1)×d
- 第 j 列数据元素的起始地址为:(j-1) ×U1×d + L1
- 数组元素 A[i,j]的地址为:Loc(A[i,j]) = L1 + (j-1)×U1×d + (i-1)×d
三、特殊矩阵
(1)对称矩阵
int Value(int A[],EntryType *item,int i,int j)
{
if (i<1||i>MAX_ROW_INDEX|| j<1||j>MAX_COL_INDEX) return FALSE;
else {
if (i>=j) k=i*(i-1)/2+j-1;
else k=j*(j-1)/2+i-1;
*item=A[k];
return TRUE;
}
}
(2)下(上)三角矩阵
int Value(int A[],EntryType *item,int i,int j)
{
if (i<1||i>MAX_ROW_INDEX||j<1||j>MAX_COL_INDEX) return FALSE;
else { if (i>=j) k=i*(i-1)/2+j;
else k=0;
*item=A[k];
return TRUE;
}
}
(3)对角矩阵
int Value(int A[ ],EntryType *item,int i,int j)
{
if (i<1||i>MAX_ROW_INDEX||j<1||j>MAX_COL_INDEX) return FALSE;
else { if (j>=(i-1)&&j<=(i+1)) k=3*(i-1)+j-i+1;
else k=0;
*item=A[k];
return TRUE;
}
}
四、稀疏矩阵的压缩存储
① 定义
② 三种压缩存储方式
- 三元组顺序表
typedef struct {
int i ,j ; //行标和列标
ElemType e ; //元素值
} Triple ;
typedef struct {
Triple data[MAXSIZE +1] ; //从 Data[1]开始使用,Data[0]不用
Int mu, nu,tu ; //矩阵的行数,列数及非零元素个数
}TSMatrix ;
T.mu = M.nu ; T.u = M.mu ; T.tu = M.tu ;//转置后行数变为列数,列数变为行数,非零元个数不变
If (T.tu) {
q=1 ;//从三元组的第一个开始使用,第 0 个不用;
for ( col = 1 ; col <= M.nu ; ++col) //从 M 的第一列开始查找
for (p=1 ; p <= M.tu ; ++p)//从三元组的第一个元素开始查询
if (M.data[p].j == col) //如果某第 P 个三元组元素的列表同 col 相同,则转置
{ T.data[q].i = M.data[p].j ;
T.data[q].j = M.data[p].i ;
T.data[q].e = M.data[p].e ;
++q ;
}
} ;
- 行逻辑链接的顺序表:
class RLSMatrix {
private:
Array<Triple> data;
//非零元三元组表,
int mu, nu, tu;
// 矩阵的行数、列数和非零元个数39
Array<int> rpos;
// 矩阵中每一行的第一个非零元
// 在三元组表中的位序
…
修改前述的稀疏矩阵的类定义,增加一个数据成员 rpos, 其值在稀疏矩阵的构造函数中确定。
for (i=1; i<=m1; ++i)
for (j=1; j<=n2; ++j) {
Q[i][j] = 0;
for (k=1; k<=n1; ++k) Q[i][j] += M[i][k] * N[k][j];
}
if Q 是非零矩阵 { // 逐行求积
for (arow=1; arow<=M.mu; ++arow) {
// 处理 M 的每一行
ctemp[] = 0;
// 累加器清零
计算 Q 中第 arow 行的积并存入 ctemp[]中;
将 ctemp[] 中非零元压缩存储到 Q.data 中;
} // for arow
} // if
RLSMatrix& RLSMarix::Product(const RLSMatrix& M, const RLSMatrix& N){
//求矩阵乘积 Q=M*N,采用行逻辑链接存储表示。
if (M.nu != N.mu) return ERROR;
sz = M.data.ListSize( );
RLSMatrix Q(M.mu, N.nu, 0, sz);// Q 初始化
if (M.tu*N.tu != 0) {// Q 是非零矩阵
for (arow=1; arow<=M.mu; ++arow) { // 处理 M 的每一行
ctemp[] = 0;// 当前行各元素累加器清零
Q.rpos[arow] = Q.tu+1;// 设置当前行第一个非零元在三元组表中的位序
for (p=M.rpos[arow]; p<M.rpos[arow+1]; ++p)
// 对当前行中每一个非零元
brow=M.data[p].j; // 找到对应元在 N 中的行号
if (brow < N.nu ) t = N.rpos[brow+1];40
else { t = N.tu+1 }
// t 指示该行中最后一个非零元的位置
for (q=N.rpos[brow]; q< t; ++q) {
ccol = N.data[q].j;// 乘积元素在 Q 中列号
ctemp[ccol] += M.data[p].e * N.data[q].e;
} // for q
} // 求得 Q 中第 crow( =arow)行的非零元
for (ccol=1; ccol<=Q.nu; ++ccol) // 压缩存储该行非零元
if (ctemp[ccol]) { // 该列元素为非零元
if (++Q.tu > Q.data.ListSize( ))
Q.data.Resize(Q.data.ListSize+Q.nu);
Q.data[Q.tu] = {arow, ccol, ctemp[ccol]};
} // if
} // for arow
} // if
return *Q;
} // Product
- 十字链表
五、广义表的基本概念
六、广义表的结构特点
七、广义表的抽象数据类型
(1)类型定义
(2)广义表的基本操作:
- 结构的创建和销毁
InitGList(&L);
DestroyGList(&L);
CreateGList(&L, S);
CopyGList(&T, L);
- 状态函数
GListLength(L);
GListDepth(L);
GListEmpty(L);
GetHead(L);
GetTail(L);
- 插入和删除操作
InsertFirst_GL(&L, e);
DeleteFirst_GL(&L, &e);
- 遍历
Traverse_GL(L, Visit());
八、总结
本文详细介绍了数据结构中的数组与广义表的概念、表示方法和存储方式。首先,文章阐述了数组的基本概念,指出数组的特点是每个数据元素可以又是一个线性表结构,并说明了数组结构的定义和表示方法,包括一维数组和二维数组,以及数组的顺序存储结构。接着,文章讨论了特殊矩阵的压缩存储方法,包括对称矩阵、下(上)三角矩阵和对角矩阵,并给出了相应的压缩存储公式和操作算法。
文章进一步介绍了稀疏矩阵的压缩存储,包括三元组顺序表、行逻辑链接的顺序表和十字链表三种存储方式,并详细描述了稀疏矩阵乘法的算法。最后,文章阐述了广义表的基本概念、结构特点和抽象数据类型,包括广义表的类型定义、基本操作和状态函数。
总体来说,本文系统地讲解了数组与广义表的理论知识,并通过实例和算法介绍了它们在实际应用中的存储和操作方法。这些内容对于理解数据结构的基本原理和编程实现具有重要意义,为读者在后续学习过程中打下了坚实的基础。通过对本文的学习,读者可以更好地掌握数组与广义表的相关知识,为解决实际问题提供理论支持。同时,本文也为进一步研究数据结构的其他领域奠定了基础。