数组和广义表

5.1 数组的定义

在这里插入图片描述
数组的定义
数组是由一组类型相同的数据元素构成的有序集合,每个数据元素称为一个数组元素(简称为元素),每个元素受n(n≥1)个线性关系的约束,每个元素在n个线性关系中的序号i1、i2、…、in称为该元素的下标,并称该数组为 n 维数组。
在这里插入图片描述
数组的特点:
元素本身可以具有某种结构,属于同一数据类型;
数组是一个具有固定格式和数量的数据集合。
数组的基本操作:⑴ 存取:给定一组下标,读出对应的数组元素;
⑵ 修改:给定一组下标,存储或修改与其相对应的数组元素。
存取和修改操作本质上只对应一种操作——寻址

5.2 数组的顺序表示和实现——一维数组

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.3 矩阵的压缩存储

特殊矩阵:包括对称矩阵、三角矩阵、对角矩阵和稀疏矩阵等。
稀疏矩阵:矩阵中有很多零元素。
压缩存储的基本思想是:
为多个值相同的元素只分配一个存储空间;
对零元素不分配存储空间。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
特殊矩阵的压缩存储——稀疏矩阵
法一:稀疏矩阵的压缩存储——三元组
将稀疏矩阵中的每个非零元素表示为:
(行号,列号,非零元素值)——三元组
定义三元组:
typedef struct
{
int i, j; //行下标,列下标
ElemType e; //非零元素值
} Triple ;
在这里插入图片描述
三元组顺序表——以顺序存储结构表示三元组表,是稀疏矩阵的一种压缩存储方式。
#define MAXSIZE 12500 //非零元个数最大值
typedef struct {
int i, j; //行下标和列下标
ElemType e;
} Triple;
typedef struct{
Triple data[MAXSIZE]; //非零元三元组表
int mu,nu,tu; //行数、列数、非零元个数
}TSMatrix;
TSMatrix a,b;
在这里插入图片描述
三元组顺序表操作——转置算法
基本思想:在A的三元组顺序表中依次找第0列、第1列、…直到最后一列的三元组,并将找到的每个三元组的行、列交换后顺序存储到B的三元组顺序表中。

  1. 设置转置后矩阵B的行数、列数和非零元个数;
  2. 在B中设置初始存储位置q;
  3. for (col=最小列号; col<=最大列号; col++)
    3.1 在A中查找列号为col的三元组;
    3.2 交换其行号和列号,存入B中q位置;
    3.3 q++;
    稀疏矩阵的转置
    Status TransposeSMatrix(TSMatrix M,TSMatrix &T)
    { int q,col,p;
    T.mu=M.nu; T.nu=M.mu; T.tu=M.tu;
    if (T.tu)
    { q=0;
    for (col=0;col<T.mu;++col)
    for(p=0;p<M.tu;++p)
    if (M.data[p].j==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;
    }
    }
    return OK;
    }
    该算法的主要时间耗费是在col和p的两重循环上。
    对于一个m行n列且非零元素个数为t的稀疏矩阵而言,该算法的时间复杂度为O(t*n)。
    例:若矩阵有200行,200列,10,000个非零元素,总共有2,000,000次处理。
    最坏情况是,当稀疏矩阵中的非零元素个数t与mn同数量级时,上述算法的时间复杂度就为O(mn2)。
    显然这种情况下,该算法效率较低。
    基本思想:顺序取,直接存。即在A中依次取三元组,交换其行号和列号放到B 中适当位置。
    在这里插入图片描述
    数据结构设计:
    引入两个数组作为辅助数据结构:
    cnum[cols]:存储矩阵A中某列的非零元素的个数;
    cpot[clos]:初值表示矩阵A中某列的第一个非零元素在B中的位置。
    cnum与cpot存在如下递推关系:在这里插入图片描述
    在这里插入图片描述
    设置转置后矩阵B的行数、列数和非零元素的个数;
  4. 计算A中每一列的非零元素个数;
  5. 计算A中每一列的第一个非零元素在B中的下标;
  6. 依次取A中的每一个非零元素对应的三元组;
    4.1 确定该元素在B中的下标q;
    4.2 将该元素的行号列号交换后存入B中q的位置;
    4.3 预置该元素所在列的下一个元素的存放位置;
    该算法中有3个平行的for循环。
    对于一个m行n列且非零元素个数为t的稀疏矩阵而言,循环次数分别为n和t两种,故此算法时间复杂度为O(n+t)。
    显然该算法优于转置算法1。
    方法二:稀疏矩阵的压缩存储——十字链表
    当矩阵中非零元素的个数和位置经过运算后变化较大时,就不宜采用顺序存储结构,而应采用链式存储结构来表示三元组。
    稀疏矩阵的链接表示采用十字链表:行链表与列链表十字交叉。
    行链表与列链表都是带表头结点的循环链表。用表头结点表征是第几行,第几列
    在这里插入图片描述

需要辅助结点作链表的表头,同时每个结点要增加两个指针域,所以只有在矩阵较大和较稀疏时才能起到节省空间的效果。
在这里插入图片描述
十字链表的类型定义
typedef struct OLNode{ //元素结点
int i,j; //非零元的行和列下标
ElemType e;
struct OLNode *right,*down; //该非零元所在行表和列
表的后继链域
} OLNode, *OLink;

typedef struct {
OLink *rhead,*chead; //行和列链表头指针数组
int mu,nu,tu;
} CrossList;
一维数组具有线性表的结构,操作简单,一般不进行插入和删除操作,只定义给定下标读取元素和修改元素的操作.
二维数组中,每个数据元素对应一对数组下标,在行方向上和列方向上都存在一个线性关系,即存在两个前驱和两个后继。也可看作是以线性表为数据元素的线性表。
n维数组中,每个数据元素对应n个下标,受n个关系的制约,其中任一个关系都是线性关系。可看作是数据元素为n-1维数组的一维数组。
因此,多维数组是对线性表的扩展。

5.4 广义表的类型定义

ADT Glist {
数据对象:D={ ei | i=1,2,…,n; n≥0;
ei∈AtomSet 或 ei∈GList,
AtomSet为某个数据对象 }
数据关系:
LR={<ei-1, ei >| ei-1 ,ei∈D, 2≤i≤n}
} ADT Glist
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

cai-4

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

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

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

打赏作者

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

抵扣说明:

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

余额充值