V第二十二讲(广义表的逻辑结构与存储结构)
第6章数组和广义表第3讲-广义表

广义表是线性表的推广,是有限个元素的序列,其逻辑 结构采用括号表示法表示如下: GL=(a1,a2,…,ai,…,an)
若n=0时称为空表 ai为广义表的第i个元素。如果ai属于原子类型,称之为广义表 GL的原子 如果ai又是一个广义表,称之为广义表GL的子表 1/18
广义表重要概念:
5/18
6.3.3 广义表的运算
1
解法1
广义表算法设计方法
整个广义表的头结点
1
∧
第1个元素 第2个元素
子表的头结点
0 a
1
∧0ຫໍສະໝຸດ b0c0 d ∧
6
子表的处理和整个广义表的处理是相似的。从这个角 度出发设计求解广义表递归算法的一般格式如下:
7/18
解法2
广义表的表结点g
g的兄弟:g->link
1
0
个算法求原子个数。
C
1
∧
0 a
1
∧
0
b
0
c
0 d ∧
原子个数为4
14/18
解:需要扫描广义表g中的所有结点,可以采用前面
介绍的广义表算法设计方法中的两种解法来实现。
15/18
//采用解法1的方法
int Count1(GLNode *g) { int n=0; GLNode *g1=g->val.sublist; while (g1!=NULL) { if (g1->tag==0) n++; else n+=Count1(g1); g1=g1->link; } return n; } //求广义表g的原子个数
广义表的长度定义为最外层包含元素个数。 广义表的深度定义为所含括弧的重数。其中,原子的深 度为0,空表的深度为1 。
第4章广义线性表-1

➢元素本身可以具有某种结构,属于同一数据类型; ➢数组是一个具有固定格式和数量的数据集合。
5
数组示例
a11 a12 … a1n
A=
a21 a22 … a2n … … ……
am1 am2 … amn
例如,元素a22受两个线性关系的约束,在行上有
一个行前驱a21和一个行后继a23,在列上有一个列 前驱a12和和一个列后继a32。
维界虽未变,但此时的a[32, 58] 不再是原来的a[32, 58]
数组的存储结构与寻址——多维数组
n(n>2)维数组一般 也采用按行优先和按列优 先两种存储方法。
(1)按行优先:最右边 的下标先变化,即最右边 下标从小到大,循环一遍 后,右边第2个下标再 变,…,最后是最左下标。
(2)按列优先:P118
每个元素占用 l 个存储单元
则a[i][j]的存储地址:
LOC ( i, j ) = a + ( j个二维数组A,行下标的范围是1到6,列下标 的范围是0到7,每个数组元素用相邻的6个字节存储, 存储器按字节编址。那么,这个数组的体积是288 个 字节。
答: Volume=m*n*L=(6-1+1)*(7- 0 +1)*6=48*6=288
…
ah1h2
Loc(al1l2) (i -l1)×(h2 -l2+1)+(j -l2)个元素 Loc(aij)
Loc(aij)=Loc(al1l2)+((i-l1)×(h2-l2+1)+(j-l2))×c
按列优先存储的寻址方法与此类似。
13
例1:如何求出a(3,2)的存储地址?
0
0 a(0,0)
1 a(1,0)
aij在本行中的序号
第10讲广义表

1
1
4
一、广义表的类型定义
广义表的特性: 有次序性,有长度,有
深度,可共享,可递归。
D
A
B
C
f
a
E
e
b
c
d
11
广义表基本操作
1.GenListNode<ElemType> *First() const 初始条件:广义表已存在。 操作结果:返回广义表的第一个元素。 2.GenListNode<ElemType> *Next(GenListNode<ElemType> *elemPtr) const 初始条件:广义表已存在,elemPtr指向的广义表元素。 操作结果:返回elemPtr指向的广义表元素的后继 3.bool Empty() const 初始条件:广义表已存在。 操作结果:如广义表为空,则返回true,否则返回false
ref (a)头结点
nextLink
tag=ATOM(1)
atom (b)原子结点
nextLink
tag=LIST(2)
subLink (c)表结点
nextLink
15
A=(),B=(x, y, z),C=(B, y, z),D=(x,(y, z)),E=(x, E)
A B C D E 0 0 0 0 0 1 2 1 1 2 ∧ 1 2 1 2 x ∧ x 1 1 2 0 1 y y ∧ 1 y 1 z ∧ 1 1 z z ∧ ∧
本讲小结
重点: 1、广义表的基本概念 2、广义表的存储
难点: 1、广义表的递归算法
22
例1 求广义表的深度 P174 DepthHelp() 例2 复制广义表
P173 CopyHelp()
第5章 数组广义表

数组的存储结构与寻址——多维数组
n(n>2)维 数组一般也采用 按行优先和按列 优先两种存储方 法。请自行推导 任一元素存储地 址的计算方法。
Loc(aijk ) = Loc(a000) +( i×m2×m3 + j×m3 + k )×c
矩阵的压缩存储
数据结构(C#版)
特殊矩阵和稀疏矩阵
特殊矩阵:矩阵中很多值相同的元素并且它们的分布 有一定的规律。
A=
0 a21 a22 a23 0 域立起来
0 0 a32 a33 a34 0 0 0 a43 a44
B=
a21 a22 a23 a32 a33 a34 a43 a44 0
t=i 映射到二维数组B中,映射关系 s=j-i+1
矩阵的压缩存储
数据结构(C#版)
对角矩阵的压缩存储
a00 a01 0 0 0
多维数组
数据结构(C#版)
数组的定义
数组是由一组类型相同的数据元素构成的有序集 合,每个数据元素称为一个数组元素(简称为元 素),每个元素受n(n≥1)个线性关系的约束,每 个元素在n个线性关系中的序号i1、i2、…、in称为 该元素的下标,并称该数组为 n 维数组。
数组的特点
元素本身可以具有某种结构,属于同一数据类型;
(a) 下三角矩阵
(b) 存储说明
(c) 计算方法
矩阵的压缩存储
对称矩阵的压缩存储
数据结构(C#版)
01 2 34 5
a00 a10 a11 a20 a21 a22 …
第0行 第1行
第2行
k aij …
n(n+1)/2-1
a n-10 aΒιβλιοθήκη -11 … an-1n-1第n-1行
《数据结构》数组和广义表

a01 a02 a11 a12 … … am-11 am-12
… a0n-1 … a1n-1 … … … am-1n-1
图5.1 二维数组元素关系
二维数组中的每一个元素aij都受到两个关系的约束: ROW(行关系)和COL(列关系)。aij+1是aij在行关系中的直 接后续元素;而ai+1j是aij在列关系中的直接后续元素。和 线性表一样,所有的数据元素属于同一数据类型。每个数 据元素对应于一组下标(i,j)。将这个概念依次类推,可以 写出n维数组的逻辑结构,但最常用的是二维数组。
5.3.1 特殊矩阵
a.对称矩阵 定义:若有一个n阶矩阵A中的元素满足下述性质 aij=aji 1≤i,j≤n 则称为n阶对称矩阵。对称矩阵可以只给每一对对称 元素分配一个存储空间,则可将n×n的二维矩阵,压 缩存储到n(n+1)/2个元的空间中。在这里讨论以行序 为主序存储其下三角(包括对角线)中的对称矩阵元素。 假设以一维数组s[n(n+1)/2]作为n阶对称矩阵A的存储 结构,数组元素s[k]于矩阵元素aij之间转换公式如下。
a00 k= 1 a10 2 a11 3 … an1 … an-1n-1 n(n+1)/2-1
图5.3 对称矩阵的压缩存储
运算
算法5.1 压缩存储的对称矩阵中的取值算法。
/* 取对称矩阵s中第i行第j列的元素 */
int Matrix_Get(int s[],int i,int j) { if(i>=j) return(s[i*(i+1)/2+j]); else return(s[j*(j+1)/2+i]); } 算法5.2 压缩存储的对称矩阵中的赋值算法。 void Matrix_Set(int s[],int i,int j,int value) { if(i>=j) s[i*(i+1)/2+j]=value; else s[j*(j+1)/2+i]=value; }
数据结构广义表

数据结构广义表介绍广义表是一种扩展了线性表的数据结构,可以存储不仅仅是数据元素,还可以存储子表,从而形成多级结构。
在广义表中,元素可以是基本类型(如整数、字符等),也可以是广义表。
广义表由一组元素组成,每个元素可以是一个基本元素或者是一个子表。
广义表可以为空,称为空表。
广义表中的元素的个数称为广义表的长度。
广义表的表示广义表可以通过两种方式进行表示:括号表示和逗号表示。
1.括号表示:使用括号将广义表括起来,每个元素之间使用逗号分隔。
例如,(1,2,3)表示一个包含3个元素的广义表,分别为1、2和3。
2.逗号表示:用逗号将广义表的元素分隔开,如果元素是基本元素,则直接写在逗号之间,如果元素是子表,则将子表表示为广义表的形式。
例如,1,2,3表示一个包含3个元素的广义表,分别为1、2和3。
广义表的操作广义表支持多种操作,包括获取广义表的长度、判断广义表是否为空、获取广义表的头、获取广义表的尾、判断两个广义表是否相等、复制广义表等。
获取广义表的长度获取广义表的长度即求广义表中元素的个数。
可以使用递归的方式来实现这个操作。
如果广义表为空,则长度为0;否则,长度等于广义表头的长度加上广义表尾的长度。
判断广义表是否为空判断广义表是否为空即判断广义表中是否没有元素。
如果广义表长度为0,则为空;否则,不为空。
获取广义表的头获取广义表的头即获取广义表中第一个元素。
如果广义表为空,则没有头;否则,头等于广义表中的第一个元素。
获取广义表的尾获取广义表的尾即获取广义表中除了第一个元素以外的所有元素。
如果广义表为空,则没有尾;否则,尾等于广义表中除了第一个元素以外的所有元素所组成的广义表。
判断两个广义表是否相等判断两个广义表是否相等即判断两个广义表中的元素是否完全相同。
如果两个广义表都为空,则相等;如果两个广义表的长度不相等,则不相等;否则,判断广义表的头是否相等,如果相等则判断广义表的尾是否相等。
复制广义表复制广义表即创建一个与原广义表相同的新广义表。
广义表总结

5.4 稀疏矩阵
在特殊矩阵中,元素的分布呈现某种规律,故一定能找 到一种合适的方法,将它们进行压缩存放。但是,在实 际应用中,我们还经常会遇到一类矩阵:其矩阵阶数很 大,非零元个数较少,零元很多,但非零元的排列没有 一定规律,我们称这一类矩阵为稀疏矩阵。(非零元不 足5%的矩阵) 按照压缩存储的概念,要存放稀疏矩阵的元素,由于没 有某种规律,除存放非零元的值外,还必须存储适当的 辅助信息,才能迅速确定一个非零元是矩阵中的哪一个 位置上的元素。下面将介绍稀疏矩阵的几种存储方法及 一些算法的实现。
(b )
(2)下三角矩阵 即矩阵的下三角部分元素是随机的,而上三角 部分元素全部相同(为某常数C)或全为0,具 体形式见下图(b)。
3.对角矩阵
若矩阵中所有非零元素都集中在以主对角线为中心的带 状区域中,区域外的值全为 0 ,则称为对角矩阵。常见 的有三对角矩阵、五对角矩阵、七对角矩阵等。 例如,下图为7×7的三对角矩阵(即有三条对角线上元 素非0)。
a00 a10 a20 ...
a11 a21 ... a22 ... ... ... ... an1n1
an10 a n11 a n12
一个下三角矩阵
下三角矩阵的压缩存储形式
思考:只存放上三角部分
以行序为主序存储上三角部分。
对于对称矩阵,除了用下三角存入外,还可用上三角形式 存放。这时数组a[0][0]存入sa[0],a[0][1]存入sa[1], a[0][2]存入sa[2]…,如下图。则sa[k]和a[i][j]之间的 对应关系为:
5.1 5.3
数组的基本概念 5.2 数组的存储结构
特殊矩阵及其压缩存储 5.4 稀疏矩阵 5.5 广义表 5.6 小结 5.7 练习
第4章 广义线性表

数组应该采用何种方式存储?
数组没有插入和删除操作,所以,不用预留空间, 适合采用顺序存储。
广义线性表——多维数组
数组的存储结构与寻址——一维数组
设一维数组的下标的范围为闭区间[ l , h ],每个 数组元素占用 c 个存储单元,则其任一元素 ai 的 存储地址可由下式确定:
矩阵的压缩存储
下三角矩阵的压缩存储 存储
0 1
下三角元素
对角线上方的常数——只存一个
2 3 4 5
k
n(n+1)/2
a00
第0行
a10
a11
a20
a21
第2行
a22
…
aij
…
an-1n-1 c
第1行
矩阵中任一元素aij在数组中的下标k与i、j的对应关系: k=
i×(i+1)/2+j
n×(n+1)/2
A=
15 0 0 0 9
0 11 0 0 0
0 0 0 0 0
0 0 6 0 0
0 0 0 0 0
0 0 0 0 0
三元组表=( (0,0,15), (1,1,11), (2,3,6), (4,0,9) ) 如何存储三元组表?
矩阵的压缩存储
稀疏矩阵的压缩存储——三元组顺序表 采用顺序存储结构存储三元组表
广义线性表——多维数组
数组示例
a11 a21 … am1 a12 a22 … am2 … … … … a1n a2n … amn
A=
例如,元素a22受两个线性关系的约束,在行上有