数据结构 课件 第05章
合集下载
《数据结构》课件

查找操作
顺序查找
二分查找
链表查找
在顺序存储结构的线性表中,查找操 作需要从线性表的第一个节点开始, 逐个比较节点的数据域,直到找到目 标数据或遍历完整个线性表。时间复 杂度为O(n)。
在有序的顺序存储结构的线性表中, 查找操作可以采用二分查找算法。每 次比较目标数据与中间节点的数据域 ,如果目标数据大于中间节点,则在 右半部分继续查找;否则在左半部分 查找。时间复杂度为O(log n)。
数据结构是算法的基础。许多算法的实现需要依赖于特定的数据结构, 因此掌握常见的数据结构是编写高效算法的关键。
数据结构在解决实际问题中具有广泛应用。无论是操作系统、数据库系 统、网络通信还是人工智能等领域,数据结构都发挥着重要的作用。
数据结构的分类
根据数据的逻辑关系,数据结构可以分为线性结构和非线 性结构。线性结构如数组、链表、栈和队列等,非线性结 构如树形结构和图形结构等。
04
数据结构操作
插入操作
顺序插入
在顺序存储结构的线性表中,插入操作 需要找到插入位置的前驱节点,修改前 驱节点的指针,使其指向新节点,然后 让新节点指向后继节点。如果线性表的 第一个节点是空节点,则将新节点作为 第一个节点。
VS
链式插入
在链式存储结构的线性表中,插入操作需 要找到插入位置的前驱节点,修改前驱节 点的指针,使其指向新节点。如果线性表 的第一个节点是空节点,则将新节点作为 第一个节点。
图
01
02
03
04
图是一种非线性数据结构,由 节点和边组成,其中节点表示 数据元素,边表示节点之间的
关系。
图具有网络结构,节点之间的 关系可以是任意复杂的,包括
双向、单向、无向等。
Chapter05_数组和广义表_数据结构(C语言版)_严蔚敏_配套ppt课件

M
1 1 2 3 3 4
1 5 3 1 2 4
3 7 -1 -1 -2 2
N
1 1 2 3 4 5
1 3 3 2 4 1
3 -1 -2 -1 2 7
行列下 标调换
1 5 3 1 2 4
1 1 2 3 3 4
3 7 -1 -1 -2 2
按行下 标排序
法1:
按照矩阵M的列序进行转置,即按三元组A的 第二个字段值(列下标)由小到大的顺序进行转置。 为了找到M中每一列中所有的非零元素,需要对其 三元组表a.data从第一行起整个扫描一遍,由于 a.data是以M的行序为主序来存放每个非零元素 的,对于M中具有相同列下标的非零元来讲,先扫 描到的非零元的行下标一定小于后扫描到的非零元 的行下标,由此得到的恰是b.data应有的顺序。
• 压缩的含义
– 为多个值相同的元素只分配一个存贮空间; – 零元素不分配或少分配存贮空间。
• 特殊矩阵:元素值相同或零元素分布有 一定规律的矩阵。 • 稀疏矩阵:元素值相同或零元素分布没 有规律的矩阵。 • 特殊矩阵的压缩存贮实际是将二维数组 的数据元素压缩到一维数组上。
特殊矩阵的压缩存储
特殊矩阵: 非零元在矩阵中的分布有一定规则
常用的稀疏矩阵的存储方法
三元组表示法 顺序存储 行逻辑联接的顺序表 带辅助行向量的二元组表示法 伪地址表示法 带行指针向量的单链表示法 链接存储 散列存储 行列表示法(十字链表) 多链表示法(正交表)
顺序存储
1、三元组表示法 用一个线性表来表示稀疏矩阵,线性表的每个 结点对应稀疏矩阵的一个非零元素。其中包括三个 域,分别为该元素的行下标、列下标和值。结点间 的先后顺序按矩阵的行优先顺序排列(跳过零元 素),将线性表用顺序的方法存储在连续的存储区 里。
数据结构C语言版ppt课件-PPT精品文档

…
an-1,0 an-1,1
…
an-1,n-1
an-1,0 an-1,1
…
…
Ann
a0,0 a1,0
a0,1 a1,1
… …
a0,n-1 a1,n-1
Ann
a0,0 a1,0
a1,1
…
…
…
an-1,n-1
对称阵
中国网页设计 xin126
下三角矩阵
第5章 数组和广义表
中国网页设计 xin126
数据结构
(C语言版)
严蔚敏、吴伟民编著 清华大学出版社 学习网站:xin126/list.asp?id=301
中国网页设计 xin126
第5章 数组和广义表
主要内容:
一、数组的定义 二、数组的表示和实现 三、矩阵的压缩存储 四、广义表的定义 五、广义表的存储结构
中国网页设计 xin126
第5章 数组和广义表
0 0 0 0 0 0
0 0 0 0 0 0
中国网页设计 xin126
第5章 数组和广义表
(2) 稀疏矩阵的存储: 若按常规方法进行存储,零值元素会占了很大空间 因此对于稀疏矩阵的存储通常采用以下两种方式: 三元组表和十字链表进行存储。
中国网页设计 xin126
第5章 数组和广义表
中国网页设计 xin126
第5章 数组和广义表
以行序为主序的求址公式:
假设每个数据元素占L个存储单元,则二维 数组A中任一元素aij的存储位置可由下式确定: LOC(i, j) = LOC(0, 0) + (n×i + j)*L 式中,LOC(i, j)是aij的存储位置,LOC(0, 0)是a00的存储位置,即二维数组A的起始存储 位置,也称为基地址或基址。b2是数组第二维 的长度,即数组A(m×n)中的列数n。
数据结构课件第5章-PPT文档资料

(a) 非紧缩方式; (b) 紧缩方式
第5章 串
5.2.2
和线性表的链式存储结构相类似,串的存储结构也可采用链 式存储结构,即用线性链表来存储串值。在这种存储结构下,存 储空间被分成一系列大小相同的结点,每个结点用data域存放字 符, link域存放指向下一个结点的指针。 这样, 一个串就可以用 一个线性链表来表示。
private { private declaration }
public { public declaration }
end;
第5章 串
这一段程序可看作一个字符串:“type private
Tstring = class
{private declaration } public {public declaration } end;
”, 其中“ ”表示换行符。Delphi的源程序编辑器提供了字符 串的查找与替换功能。 选择“Search”菜单中的“Replace”项, 在对话框中输入要查找字符串‘private’及替代串‘protected’, 如 图 5.1 所 示 , 则 执 行 命 令 后 以 上 程 序 中 的 关 键 字 ‘ private’ 被 ‘protected’替代。
第5章 串 串中任意个连续的字符组成的子序列称为该串的子串。包含 子串的串称为主串。通常称字符在序列中的序号为该字符在串中 的位置。子串在主串中的位置可以用子串的第一个字符在主串中 的位置来表示。
例如, 假设a、 b、 c、 d为如下的四个串:
a =‘Data’
b =‘Structure’
c =‘Data Structure’ d =‘Data Structure’
const maxlen = 允许的串最大长度;
第5章 串
5.2.2
和线性表的链式存储结构相类似,串的存储结构也可采用链 式存储结构,即用线性链表来存储串值。在这种存储结构下,存 储空间被分成一系列大小相同的结点,每个结点用data域存放字 符, link域存放指向下一个结点的指针。 这样, 一个串就可以用 一个线性链表来表示。
private { private declaration }
public { public declaration }
end;
第5章 串
这一段程序可看作一个字符串:“type private
Tstring = class
{private declaration } public {public declaration } end;
”, 其中“ ”表示换行符。Delphi的源程序编辑器提供了字符 串的查找与替换功能。 选择“Search”菜单中的“Replace”项, 在对话框中输入要查找字符串‘private’及替代串‘protected’, 如 图 5.1 所 示 , 则 执 行 命 令 后 以 上 程 序 中 的 关 键 字 ‘ private’ 被 ‘protected’替代。
第5章 串 串中任意个连续的字符组成的子序列称为该串的子串。包含 子串的串称为主串。通常称字符在序列中的序号为该字符在串中 的位置。子串在主串中的位置可以用子串的第一个字符在主串中 的位置来表示。
例如, 假设a、 b、 c、 d为如下的四个串:
a =‘Data’
b =‘Structure’
c =‘Data Structure’ d =‘Data Structure’
const maxlen = 允许的串最大长度;
数据结构 检索方法

顺序查找
1.顺序查找的基本思想 . 顺序查找是一种最简单的查找方法,它的基本思想是: 顺序查找是一种最简单的查找方法,它的基本思想是:从 表的一端开始,顺序扫描线性表,依次将扫描到的结点关键字 表的一端开始, 顺序扫描线性表, 和待找的值K相比较,若相等,则查找成功, 和待找的值K相比较,若相等,则查找成功,若整个表扫描完 仍末找到关键字等于K的元素,则查找失败。 毕,仍末找到关键字等于K的元素,则查找失败。 顺序查找既适用于顺序表,也适用于链表。若用顺序表, 顺序查找既适用于顺序表,也适用于链表。若用顺序表, 既适用于顺序表 查找可从前往后扫描,也可从后往前扫描,但若采用单链表, 查找可从前往后扫描,也可从后往前扫描,但若采用单链表, 则只能从前往后扫描。另外, 则只能从前往后扫描。另外,顺序查找的表中元素可以是无序 的。 衡量一个查找算法性能优劣的标准是平均查找长度, 衡量一个查找算法性能优劣的标准是平均查找长度,即在 查找成功的情况下所需的平均比较次数。对于等概率顺序查找, 查找成功的情况下所需的平均比较次数。对于等概率顺序查找, 它的平均查找长度为: 它的平均查找长度为 : ( n+1) /2。 若失败 , 平均比较结点个 ) 。 若失败, 数为n+1。 。 数为
查找 K=21 的示意图
0
05
1
13
2
19 [
3
21
4
37
5
] 56
6
64
7
74
8
80
9 10
88 92
mid low hig (d ) 经过三次比较后的情形 图 8-1 (array[mid].key=21)
查找成功) 查找 K=21 的示意图 (查找成功 查找成功
数据结构详解.ppt

n维: Loc[j1,j2,….,jn]=Loc[0,0,…,0]+ (b2*b3*…*bn*j1+b3*b4*…*bn*j2+….+bn*jn-1+jn)*h
令C1=b2*b3*…*bn*h C2=b3*b4*….*bn*h …….. Cn-1=bn*h Ci=Ci+1*bi+1 Cn=h
Loc[j1,j2,….jn]=Loc[0,0,…,0]+ji*Ci
lsls为广义表的为广义表的名称名称nn为广义表的为广义表的长度长度aaii为广义表的为广义表的元素元素每个元素既可以是单个不可分的元素每个元素既可以是单个不可分的元素广义表广义表lsls的的原子原子也可以是一个广义表也可以是一个广义表广义表广义表lsls的的子表子表一般用大写字母表示广义表的名称用小写字母表示原子一般用大写字母表示广义表的名称用小写字母表示原子非空广义表的第一个元素称为非空广义表的第一个元素称为lsls的的表头表头headhead其余元素组成的表其余元素组成的表称为称为lsls的的表尾表尾tailtail广义表是线性表的推广又称列表1
*( A.base+off)=e;
return OK; }
5.3 矩阵的压缩存储
一、特殊矩阵 1.对称矩阵 n阶矩阵满足:aij=aji a11 a12 a13 a31 a32 a33 a41 a42 a43 a14 a34 a44 a15 a35 a45 a55 a65 a16 a36 a46 a56 a66
k=
i(i-1)/2+j j(j-1)/2+i
i j i<j
称sa[1..n(n+1)/2]为a[1..n2]的压缩矩阵 压缩矩阵 a11 a21 a22 a31 a32 a33 a41 a42 a43 a44 a51 a52 a53 a54 a55 a61 a62 a63 a64 a65 a66
严蔚敏版数据结构第五章
一个n维数组可以看成是由若干个n-1维数组组成的线性表。
5
N维数组的数据类型定义
n_ARRAY = (D, R)
其中:
数据对象:D = {aj1,j2…jn| ji为数组元素的第i 维下标 ,aj1,j2…jn Elemset} 数据关系:R = { R1 ,R2,…. Rn } Ri = {<aj1,j2,…ji…jn , aj1,j2,…ji+1…jn >| aj1,j2,…ji…jn , aj1,j2,…ji+1…jn D } 基本操作:构造数组、销毁数组、读数组元素、写数组元素
6的每个元素占五个字节将其按列优先次序存储在起始地址为1000的内存单元中则元素a55的地址是南京理工大学2001一1315分12102二维数组m的元素是4个字符每个字符占一个存储单元组成的串行下标k的范围从0到4列下标j的范围从0到5m按行存储时元素m35的起始地址与m按列存储时元素m43的起始地址相同
10
二维数组
三维数组
行向量 下标 i 列向量 下标 j
页向量 下标 i 行向量 下标 j 列向量 下标 k
11
三维数组
– 各维元素个数为 m1, m2, m3 – 下标为 i1, i2, i3的数组元素的存储地址: – (按页/行/列存放)
LOC ( i1, i2, i3 ) = a + ( i1* m2 * m3 + i2* m3 + i3 ) * l 前i1页总 第i1页的 元素个数 前i2行总
前i行元素总数 第i行第j个元素前元素个数
24
若 i j,数组元素A[i][j]在数组B中的存 放位置为 n + (n-1) + (n-2) + + (n-i+1) + j-i = = (2*n-i+1) * i / 2 + j-i = = (2*n-i-1) * i / 2 + j 若i > j,数组元素A[i][j]在矩阵的下三角 部分,在数组 B 中没有存放。因此,找它 的对称元素A[j][i]。 A[j][i]在数组 B 的第 (2*n-j-1) * j / 2 + i 的位置中找到。
5
N维数组的数据类型定义
n_ARRAY = (D, R)
其中:
数据对象:D = {aj1,j2…jn| ji为数组元素的第i 维下标 ,aj1,j2…jn Elemset} 数据关系:R = { R1 ,R2,…. Rn } Ri = {<aj1,j2,…ji…jn , aj1,j2,…ji+1…jn >| aj1,j2,…ji…jn , aj1,j2,…ji+1…jn D } 基本操作:构造数组、销毁数组、读数组元素、写数组元素
6的每个元素占五个字节将其按列优先次序存储在起始地址为1000的内存单元中则元素a55的地址是南京理工大学2001一1315分12102二维数组m的元素是4个字符每个字符占一个存储单元组成的串行下标k的范围从0到4列下标j的范围从0到5m按行存储时元素m35的起始地址与m按列存储时元素m43的起始地址相同
10
二维数组
三维数组
行向量 下标 i 列向量 下标 j
页向量 下标 i 行向量 下标 j 列向量 下标 k
11
三维数组
– 各维元素个数为 m1, m2, m3 – 下标为 i1, i2, i3的数组元素的存储地址: – (按页/行/列存放)
LOC ( i1, i2, i3 ) = a + ( i1* m2 * m3 + i2* m3 + i3 ) * l 前i1页总 第i1页的 元素个数 前i2行总
前i行元素总数 第i行第j个元素前元素个数
24
若 i j,数组元素A[i][j]在数组B中的存 放位置为 n + (n-1) + (n-2) + + (n-i+1) + j-i = = (2*n-i+1) * i / 2 + j-i = = (2*n-i-1) * i / 2 + j 若i > j,数组元素A[i][j]在矩阵的下三角 部分,在数组 B 中没有存放。因此,找它 的对称元素A[j][i]。 A[j][i]在数组 B 的第 (2*n-j-1) * j / 2 + i 的位置中找到。
【2019年整理】数据结构课件第5章
if (pos >maxlen) or (pos < 1) or (s.curlen = maxlen) then showmessage(’error’)
else begin {若插入位置超出串s的长度, } if pos > s.curlen then pos:= s.curlen; {则将其调整至串s的末尾} if s.curlen+t.curlen<maxlen then len:= s.curlen+t.curlen else len:=maxlen; {计算新串长}
为串的长度。 零个字符的串称为空串(null string),长度为零。
第5章 串
串中任意个连续的字符组成的子序列称为该串的子串。包含
子串的串称为主串。通常称字符在序列中的序号为该字符在串中 的位置。子串在主串中的位置可以用子串的第一个字符在主串中 的位置来表示。 例如, 假设a、 b、 c、 d为如下的四个串: a =‘Data’ c =‘Data Structure’ b =‘Structure’ d =‘Data Structure’
一个线性链表来表示。
由于串结构的特殊性,在串的链表结构中常常涉及到结点的
大小问题,即如何确定结点的data域存放字符的个数问题。 通常
情况下,结点的大小为4或1,如图5.3所示。当结点的大小为4时, 串所占用的结点中最后一个结点的 data域不一定全被串值占满,
这时通常补上“#”或其他的非串值字符。
第5章 串
第5章 串
5.1 串的应用实例及概念
5.2 串的存储结构 5.3 串的基本操作 5.4 串的ADT定义及类定义 5.5 实习五:串的演示程序
第5章 串
5.1 串的应用实例及概念
数据结构-清华大学-殷人昆-05
其中, mark 是处理标记; vertex1和vertex2是该 边两顶点位置。Path1 指向下一条依附 vertex1 的边;path2 指向下一条依附 vertex2 的边。
138-28
对于带权图还需设置一个存放与该边相关的权 值的域 cost。
顶点结点的结构
data Firstout
向的。
138-3
有向图与无向图 在有向图中,顶点对 <x, y> 是 有序的。在无向图中,顶点对(x, y)是无序的。
完全图 若有 n 个顶点的无向图有 n(n-1)/2 条边, 则此图为完全无向图。有 n 个顶点的有向图有 n(n-1) 条边, 则此图为完全有向图。
0
0
00
1
121 2
1
//最大顶点个数
typedef char VType;
//顶点数据类型
typedef int WType;
//边上权值类型
typedef struct {
//静态存储定义
VType verticesList[maxVertices]; //顶点表
WType Edge[maxVertices][maxVertices];
138-8
图的存储表示
邻接矩阵 (Adjacency Matrix)
在图的邻接矩阵表示中,有一个记录各个顶点信 息的顶点表,还有一个表示各个顶点之间关系的 邻接矩阵。
设图 A = (V, E)是一个有 n 个顶点的图, 图的邻接 矩阵是一个二维数组 A.edge[n][n],定义:
A.Edge[
if ( v != -1 ) { for ( int col = 0; col < G.numVertices; col++ ) if ( G.Edge[v][col] > 0 && G.Edge[v][col] < maxValue ) return col; //顺序检测第 v 行寻找第一个邻接顶点 //对于无权图,maxValue应为INT_MAX
138-28
对于带权图还需设置一个存放与该边相关的权 值的域 cost。
顶点结点的结构
data Firstout
向的。
138-3
有向图与无向图 在有向图中,顶点对 <x, y> 是 有序的。在无向图中,顶点对(x, y)是无序的。
完全图 若有 n 个顶点的无向图有 n(n-1)/2 条边, 则此图为完全无向图。有 n 个顶点的有向图有 n(n-1) 条边, 则此图为完全有向图。
0
0
00
1
121 2
1
//最大顶点个数
typedef char VType;
//顶点数据类型
typedef int WType;
//边上权值类型
typedef struct {
//静态存储定义
VType verticesList[maxVertices]; //顶点表
WType Edge[maxVertices][maxVertices];
138-8
图的存储表示
邻接矩阵 (Adjacency Matrix)
在图的邻接矩阵表示中,有一个记录各个顶点信 息的顶点表,还有一个表示各个顶点之间关系的 邻接矩阵。
设图 A = (V, E)是一个有 n 个顶点的图, 图的邻接 矩阵是一个二维数组 A.edge[n][n],定义:
A.Edge[
if ( v != -1 ) { for ( int col = 0; col < G.numVertices; col++ ) if ( G.Edge[v][col] > 0 && G.Edge[v][col] < maxValue ) return col; //顺序检测第 v 行寻找第一个邻接顶点 //对于无权图,maxValue应为INT_MAX
数据结构05数组和广义表11
2021/11/8
12
设有m×n二维数组Amn,下面我们看按元素的下标求其 地址的计算:
以“行为主序”的分配为例:设数组的基址为LOC(a11), 每个数组元素占据l个地址单元,那么aij 的物理地址可用一 线性寻址函数计算:
LOC(aij) = LOC(a11) + ( (i-1)*n + j-1 ) * l 在C语言中,数组中每一维的下界定义为0,则:
(1) 取值操作:给定一组下标,读其对应的数据元素。
(2) 赋值操作:给定一组下标,存储或修改与其相对应的
数据元素。
我们着重研究二维和三维数组,因为它们的应用是广泛的,
尤其是二维数组。
2021/11/8
9
5.1.3 数组的存储结构
• 通常,数组在内存中被映象为向量,即用向量作为数组的 一种存储结构,这是因为内存的地址空间是一维的,数组的行 列固定后,通过一个映象函数,则可根据数组元素的下标得到 它的存储地址。
• 任一数据元素的存储地址可由公式算出:
Loc(a i,j)=loc(a 0,0)+(i*n+j)*L
– 以列序为主序的顺序存储
• 在以列序为主序的存储方式中,数组元素按列向量排列, 即第j+1个列向量紧接在第j个列向量之后, 把所有数组 元素顺序存放在一块连续的存储单元中。
• 任一数据元素的存储地址可由公式算出
–Loc(a i,j)=loc(a c1,c2)+[(j-c1)*(d1-c1+1)+(i-c1)]*L
2021/11/8
8
5.1.2 数组的基本操作
数组一旦被定义,它的维数和维界就不再改变。因此,除了 结构的初始化和销毁之外,数组的基本操作一般不会含有元素 的插入或删除等操作,数组只有访问数组元素和修改元素值的 操作。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第5章 数组和广义表(Arrays & Lists) 章 数组和广义表( )
数组和广义表的特点:一种特殊的线性表 数组和广义表的特点:
① 元素的值并非原子类型,可以再分解,表中元素也是一 元素的值并非原子类型,可以再分解, 个线性表(即广义的线性表)。 个线性表(即广义的线性表)。 所有数据元素仍属同一数据类型 同一数据类型。 ② 所有数据元素仍属同一数据类型。
11
数组基址指针
各维长度保 存区指针
映像函数Ci 映像函数Ci 保存区指针
Status DestroyArray(Array &A) //销毁数组 销毁数组A { //销毁数组A if ( ! A . base ) return ERROR; free( A . base ); A . base = NULL; if ( ! A.bounds ) return ERROR; free( A . bounds ); A . bounds = NULL; if ( !A.constants ) return ERROR; free ( A. constants ) ; A. constants = NULL; return OK; }
2
一维数组的特点: 个下标, 一维数组的特点: 1个下标,ai 是ai+1的直接前驱 二维数组的特点: 个下标,每个元素a 二维数组的特点: 2个下标,每个元素 i,j受到两个关系
(行关系和列关系)的约束: 行关系和列关系)的约束: a11 a12 … a1n a21 a22 … a2n 一个m× 的二维数组可以 一个 ×n的二维数组可以 … … …… 看成是m行的一维数组 行的一维数组, 看成是 行的一维数组,或 am1 am2 … amn 列的一维数组。 者n列的一维数组。 列的一维数组
Amn=
N维数组的特点: n个下标,每个元素受到n个关系约束 维数组的特点: 个下标,每个元素受到n
一个n维数组可以看成是由若干个n- 维数组组成的线性表 维数组组成的线性表。 一个 维数组可以看成是由若干个 -1维数组组成的线性表。 维数组可以看成是由若干个
3
N维数组的数据类型定义 维数组的数据类型定义 n_ARRAY = (D, R)
例2:已知二维数组 m,m按行存储的元素地址公式是: :已知二维数组A 按行存储的元素地址公式是:
Loc(aij)= Loc(a11)+[(i-1)*m+(j-1)]*K , 按列存储的公式是? 按列存储的公式是?
尽管是方阵,但公式仍不同) Loc(aij)=Loc(a11)+[(j-1)*m+(i-1)]*K (尽管是方阵,但公式仍不同)
数组基址
∑C j
i i
前面若干元素占用 的地址字节总数
其中C 其中 n=L, Ci-1=bi×Ci, 1<i≤n ,
一个元 素长度 第i维长度 与所存元素个数有关的系 数,可用递推法求出
8
N维数组的顺序存储表示(见教材P93) 维数组的顺序存储表示(见教材P93 P93) 维数组的顺序存储表示 #define MAX_ARRAY_DIM 8 //假设最大维数为 假设最大维数为8 假设最大维数为 typedef struct{ ELemType *base; //数组元素基址 数组元素基址 int dim; //数组维数 数组维数 int *bound; //数组各维长度信息保存区基址 数组各维长度信息保存区 数组各维长度信息保存区基址 int *constants; //数组映像函数常量的基址 数组映像函数常量 数组映像函数常量的基址 }Array; 数组的基本操作函数说明( 数组的基本操作函数说明(有5个) 个 请阅读教材P93 95) P93(请阅读教材P93-95)
10
for(i=0;i<dim;++i){ A.bounds[i]=va_arg(ap, i); if(A.bounds[i]<0) return UNDERFLOW; elemtotal *=A.bounds[i]; } va_end(ap); A.base=(ElemType * )malloc(elemtotal * sizeof(ElemType)); if(!A.base) exit(OVERFLOW); A.constants=(int * )malloc(dim *sizeof(int)); if(!A.constans) exit(OVERFLOW); A.constans[dim-1]=1; for(i=dim-2;i>=0;--i) A.constants[i]=A.bounds[i+1]*A.constants[i+1]; return OK; }
5.1 5.2 5.3 5.4 5.5
数组的定义 数组的顺序表示和实现 矩阵的压缩存储 广义表的定义 广义表的存储结构
1
5.1 数组的定义
数组: 由一组名字相同、 数组: 由一组名字相同、下标不同的变量构成
注意: 本章所讨论的数组与高级语言中的数组有所区别: 注意: 本章所讨论的数组与高级语言中的数组有所区别:高 级语言中的数组是顺序结构; 本章的数组既可以是顺序的, 级语言中的数组是顺序结构;而本章的数组既可以是顺序的, 也可以是链式结构,用户可根据需要选择。 也可以是链式结构,用户可根据需要选择。 讨论:“数组的处理比其它复杂的结构要简单”,对吗? 讨论: 数组的处理比其它复杂的结构要简单” 对吗? 对的。因为: 答:对的。因为: 统一的类型; 数组中各元素具有统一的类型 ① 数组中各元素具有统一的类型; 数组元素的下标一般具有固定的上界和下界 固定的上界和下界, ② 数组元素的下标一般具有固定的上界和下界,即数组一 旦被定义,它的维数和维界就不再改变。 旦被定义,它的维数和维界就不再改变。 数组的基本操作比较简单 基本操作比较简单, ③数组的基本操作比较简单,除了结构的初始化和销毁之 只有存取元素和修改元素值的操作。 外,只有存取元素和修改元素值的操作。
5
无论规定行优先或列优先, 无论规定行优先或列优先,只要知道以下三要素便可随时求出 任一元素的地址(这样数组中的任一元素便可以随机存取! 任一元素的地址(这样数组中的任一元素便可以随机存取!): ①开始结点的存放地址(即基地址) 开始结点的存放地址(即基地址) 维数和每维的上、下界; ②维数和每维的上、下界; ac1,c2 … ac1,d2 ③每个数组元素所占用的单元数 Amn= … aij … ad1,c2 … ad1,d2 则行优先存储时的地址公式为: 行优先存储时的地址公式为: 存储时的地址公式为 LOC(aij)=LOC(ac1,c2)+[(i-c1)*(d2-c2+1)+j-c2)]*L , aij之前的 数组基址 a 本行前面的
行数 总列数, 总列数,即 第2维长度 元素个数
ij本行前面的
补充:计算二维数组元素地址的通式 补充:
设一般的二维数组是A[c 这里c 不一定是0 设一般的二维数组是A[c1..d1, c2..d2],这里c1,c2不一定是0。
单个元素 长度
二维数组列优先存储的通式为: 列优先存储的通式为 二维数组列优先存储的通式为: LOC(aij)=LOC(ac1,c2)+[(j-c2)*(d1-c1+1)+i-c1)]*L ,
12
Status Locate(Array A, va_list ap, int &off) {
9
即Ci信息保存区
数组的基本操作函数说明( 个 见教材P93 95) P93数组的基本操作函数说明(5个) (见教材P93-95)
Status InitArray(Array &A,int dim,…){ //若维数dim和各维长度合法, 构造相应的数组A并返回OK //若维数dim和各维长度合法,则构造相应的数组A并返回OK 若维数dim和各维长度合法 if(dim<1||dim>MAX_ARRAY_DIM) return ERROR; A.dim=dim; A.bounds=(int *)malloc(dim * sizeof(int)); if(!a.bounds) exit(OVERFLOW); /*若各维长度合法 则存入A.bounds,并求出A 若各维长度合法, A.bounds,并求出 /*若各维长度合法,则存入A.bounds,并求出A的元素总 数elemtotal*/ elemtotal=1; va_start(ap, dim); /*ap为va_list类型,是存放变长参数表 /*ap为va_list类型 类型, 信息的类型,dim参数的写法是类C ,dim参数的写法是类 信息的类型,dim参数的写法是类C的*/
数组的抽象数据类型定义略 参见教材P90 数组的抽象数据类型定义略,参见教材P90 疑问:为何书中写成i=2,…n? i=2,… 疑问:为何书中写成i=2,
4
5.2 数组的顺序存储表示和实现
问题:计算机的存储结构是一维的,而数组一般是多维的, 问题:计算机的存储结构是一维的,而数组一般是多维的, 怎样存放? 怎样存放? 解决办法:事先约定按某种次序将数组元素排成一列序列, 解决办法:事先约定按某种次序将数组元素排成一列序列, 然后将这个线性序列存入存储器中。 然后将这个线性序列存入存储器中。 例如:在二维数组中,我们既可以规定按行存储, 例如:在二维数组中,我们既可以规定按行存储,也可以 规定按列存储。 规定按列存储。 注意: 注意: • 若规定好了次序,则数组中任意一个元素的存放地址便 若规定好了次序, 有规律可寻,可形成地址计算公式; 有规律可寻,可形成地址计算公式; • 约定的次序不同,则计算元素地址的公式也有所不同; 约定的次序不同,则计算元素地址的公式也有所不同; • C和PASCAL中一般采用行优先顺序;FORTRAN采用列优先。 PASCAL中一般采用行优先顺序 FORTRAN采用列优先 中一般采用行优先顺序; 采用列优先。
数组和广义表的特点:一种特殊的线性表 数组和广义表的特点:
① 元素的值并非原子类型,可以再分解,表中元素也是一 元素的值并非原子类型,可以再分解, 个线性表(即广义的线性表)。 个线性表(即广义的线性表)。 所有数据元素仍属同一数据类型 同一数据类型。 ② 所有数据元素仍属同一数据类型。
11
数组基址指针
各维长度保 存区指针
映像函数Ci 映像函数Ci 保存区指针
Status DestroyArray(Array &A) //销毁数组 销毁数组A { //销毁数组A if ( ! A . base ) return ERROR; free( A . base ); A . base = NULL; if ( ! A.bounds ) return ERROR; free( A . bounds ); A . bounds = NULL; if ( !A.constants ) return ERROR; free ( A. constants ) ; A. constants = NULL; return OK; }
2
一维数组的特点: 个下标, 一维数组的特点: 1个下标,ai 是ai+1的直接前驱 二维数组的特点: 个下标,每个元素a 二维数组的特点: 2个下标,每个元素 i,j受到两个关系
(行关系和列关系)的约束: 行关系和列关系)的约束: a11 a12 … a1n a21 a22 … a2n 一个m× 的二维数组可以 一个 ×n的二维数组可以 … … …… 看成是m行的一维数组 行的一维数组, 看成是 行的一维数组,或 am1 am2 … amn 列的一维数组。 者n列的一维数组。 列的一维数组
Amn=
N维数组的特点: n个下标,每个元素受到n个关系约束 维数组的特点: 个下标,每个元素受到n
一个n维数组可以看成是由若干个n- 维数组组成的线性表 维数组组成的线性表。 一个 维数组可以看成是由若干个 -1维数组组成的线性表。 维数组可以看成是由若干个
3
N维数组的数据类型定义 维数组的数据类型定义 n_ARRAY = (D, R)
例2:已知二维数组 m,m按行存储的元素地址公式是: :已知二维数组A 按行存储的元素地址公式是:
Loc(aij)= Loc(a11)+[(i-1)*m+(j-1)]*K , 按列存储的公式是? 按列存储的公式是?
尽管是方阵,但公式仍不同) Loc(aij)=Loc(a11)+[(j-1)*m+(i-1)]*K (尽管是方阵,但公式仍不同)
数组基址
∑C j
i i
前面若干元素占用 的地址字节总数
其中C 其中 n=L, Ci-1=bi×Ci, 1<i≤n ,
一个元 素长度 第i维长度 与所存元素个数有关的系 数,可用递推法求出
8
N维数组的顺序存储表示(见教材P93) 维数组的顺序存储表示(见教材P93 P93) 维数组的顺序存储表示 #define MAX_ARRAY_DIM 8 //假设最大维数为 假设最大维数为8 假设最大维数为 typedef struct{ ELemType *base; //数组元素基址 数组元素基址 int dim; //数组维数 数组维数 int *bound; //数组各维长度信息保存区基址 数组各维长度信息保存区 数组各维长度信息保存区基址 int *constants; //数组映像函数常量的基址 数组映像函数常量 数组映像函数常量的基址 }Array; 数组的基本操作函数说明( 数组的基本操作函数说明(有5个) 个 请阅读教材P93 95) P93(请阅读教材P93-95)
10
for(i=0;i<dim;++i){ A.bounds[i]=va_arg(ap, i); if(A.bounds[i]<0) return UNDERFLOW; elemtotal *=A.bounds[i]; } va_end(ap); A.base=(ElemType * )malloc(elemtotal * sizeof(ElemType)); if(!A.base) exit(OVERFLOW); A.constants=(int * )malloc(dim *sizeof(int)); if(!A.constans) exit(OVERFLOW); A.constans[dim-1]=1; for(i=dim-2;i>=0;--i) A.constants[i]=A.bounds[i+1]*A.constants[i+1]; return OK; }
5.1 5.2 5.3 5.4 5.5
数组的定义 数组的顺序表示和实现 矩阵的压缩存储 广义表的定义 广义表的存储结构
1
5.1 数组的定义
数组: 由一组名字相同、 数组: 由一组名字相同、下标不同的变量构成
注意: 本章所讨论的数组与高级语言中的数组有所区别: 注意: 本章所讨论的数组与高级语言中的数组有所区别:高 级语言中的数组是顺序结构; 本章的数组既可以是顺序的, 级语言中的数组是顺序结构;而本章的数组既可以是顺序的, 也可以是链式结构,用户可根据需要选择。 也可以是链式结构,用户可根据需要选择。 讨论:“数组的处理比其它复杂的结构要简单”,对吗? 讨论: 数组的处理比其它复杂的结构要简单” 对吗? 对的。因为: 答:对的。因为: 统一的类型; 数组中各元素具有统一的类型 ① 数组中各元素具有统一的类型; 数组元素的下标一般具有固定的上界和下界 固定的上界和下界, ② 数组元素的下标一般具有固定的上界和下界,即数组一 旦被定义,它的维数和维界就不再改变。 旦被定义,它的维数和维界就不再改变。 数组的基本操作比较简单 基本操作比较简单, ③数组的基本操作比较简单,除了结构的初始化和销毁之 只有存取元素和修改元素值的操作。 外,只有存取元素和修改元素值的操作。
5
无论规定行优先或列优先, 无论规定行优先或列优先,只要知道以下三要素便可随时求出 任一元素的地址(这样数组中的任一元素便可以随机存取! 任一元素的地址(这样数组中的任一元素便可以随机存取!): ①开始结点的存放地址(即基地址) 开始结点的存放地址(即基地址) 维数和每维的上、下界; ②维数和每维的上、下界; ac1,c2 … ac1,d2 ③每个数组元素所占用的单元数 Amn= … aij … ad1,c2 … ad1,d2 则行优先存储时的地址公式为: 行优先存储时的地址公式为: 存储时的地址公式为 LOC(aij)=LOC(ac1,c2)+[(i-c1)*(d2-c2+1)+j-c2)]*L , aij之前的 数组基址 a 本行前面的
行数 总列数, 总列数,即 第2维长度 元素个数
ij本行前面的
补充:计算二维数组元素地址的通式 补充:
设一般的二维数组是A[c 这里c 不一定是0 设一般的二维数组是A[c1..d1, c2..d2],这里c1,c2不一定是0。
单个元素 长度
二维数组列优先存储的通式为: 列优先存储的通式为 二维数组列优先存储的通式为: LOC(aij)=LOC(ac1,c2)+[(j-c2)*(d1-c1+1)+i-c1)]*L ,
12
Status Locate(Array A, va_list ap, int &off) {
9
即Ci信息保存区
数组的基本操作函数说明( 个 见教材P93 95) P93数组的基本操作函数说明(5个) (见教材P93-95)
Status InitArray(Array &A,int dim,…){ //若维数dim和各维长度合法, 构造相应的数组A并返回OK //若维数dim和各维长度合法,则构造相应的数组A并返回OK 若维数dim和各维长度合法 if(dim<1||dim>MAX_ARRAY_DIM) return ERROR; A.dim=dim; A.bounds=(int *)malloc(dim * sizeof(int)); if(!a.bounds) exit(OVERFLOW); /*若各维长度合法 则存入A.bounds,并求出A 若各维长度合法, A.bounds,并求出 /*若各维长度合法,则存入A.bounds,并求出A的元素总 数elemtotal*/ elemtotal=1; va_start(ap, dim); /*ap为va_list类型,是存放变长参数表 /*ap为va_list类型 类型, 信息的类型,dim参数的写法是类C ,dim参数的写法是类 信息的类型,dim参数的写法是类C的*/
数组的抽象数据类型定义略 参见教材P90 数组的抽象数据类型定义略,参见教材P90 疑问:为何书中写成i=2,…n? i=2,… 疑问:为何书中写成i=2,
4
5.2 数组的顺序存储表示和实现
问题:计算机的存储结构是一维的,而数组一般是多维的, 问题:计算机的存储结构是一维的,而数组一般是多维的, 怎样存放? 怎样存放? 解决办法:事先约定按某种次序将数组元素排成一列序列, 解决办法:事先约定按某种次序将数组元素排成一列序列, 然后将这个线性序列存入存储器中。 然后将这个线性序列存入存储器中。 例如:在二维数组中,我们既可以规定按行存储, 例如:在二维数组中,我们既可以规定按行存储,也可以 规定按列存储。 规定按列存储。 注意: 注意: • 若规定好了次序,则数组中任意一个元素的存放地址便 若规定好了次序, 有规律可寻,可形成地址计算公式; 有规律可寻,可形成地址计算公式; • 约定的次序不同,则计算元素地址的公式也有所不同; 约定的次序不同,则计算元素地址的公式也有所不同; • C和PASCAL中一般采用行优先顺序;FORTRAN采用列优先。 PASCAL中一般采用行优先顺序 FORTRAN采用列优先 中一般采用行优先顺序; 采用列优先。