数据结构 第5章广义表
数据结构第5章 串和广义表

5.1 串的定义和基本运算
• (4)串的连接StrCat(S,T)。 • 初始条件:串S和T存在。 • 操作结果:将串T的值连接在串S的后面。 • (5)求子串SubString(Sub,S,pos,len)。 • 初始条件:串S存在,1≤pos≤StrLength(S)且
1≤len≤StrLength(S)-pos+1。 • 操作结果:用Sub返回串S的第pos个字符起长度为len的
1≤len≤StrLength(S)-pos+1。 • 操作结果:从串S中删除第pos个字符起长度为len的子串。 • (9)串的替换StrReplace(S,T,V)。 • 初始条件:串S,T和V存在,且T是非空串。 • 操作结果:用V替换串S中出现的所有与T相等的不重叠子
串。 • (10)判断串空StrEmpty(S)。 • 初始条件:串S存在。 • 操作结果:若串S为空串,则返回1;否则返回0。
• (1)非紧凑存储。设串S="Hello boy",计算机字长为32 位(4个Byte),用非紧凑格式一个地址只能存一个字符, 如图5-2所示。其优点是运算处理简单,但缺点是存储空 间十分浪费。
• (2)紧凑存储。同样存储S="Hello boy",用紧凑格式一 个地址能存四个字符,如图5-3所示。紧凑存储的优点是 空间利用率高,缺点是对串中字符处理的效率低。
•}
5.3 串的基本运算的实现
• (3)求子串操作。求串S从第pos位置开始,长度为len的 子串,并将其存入到串Sub中。操作成功返回1,不成功 返回0。其算法描述如下:
• int SubString(String *S,String *Sub,int pos,int len)
数据结构第五章 数组与广义表

压缩存储方法:只需要存储下三角 (含对角线)上的元素。可节省一 半空间。
可以使用一维数组Sa[n(n+1)/2]作为n阶对称矩阵A的存 储结构,且约定以行序为主序存储各个元素,则在Sa[k]和矩
阵元素aij之间存在一一对应关系: (下标变换公式)
i(i+1)/2 + j 当i≥j k = j(j+1)/2 + i 当i<j
q = cpot[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; ++cpot[col]; }
分析算法FastTransposeSMatrix的时间 复杂度:
for (col=1; col<=M.nu; ++col) … … for (t=1; t<=M.tu; ++t) … … for (col=2; col<=M.nu; ++col) … … for (p=1; p<=M.tu; ++p) … …
//对当前行中每一个非零元
处
brow=M.data[p].j;
理
if (brow < N.nu ) t = N.rpos[brow+1];
M
else { t = N.tu+1 }
的
for (q=N.rpos[brow]; q< t; ++q) { ccol = N.data[q].j; // 乘积元素在Q中列号
一、三元组顺序表
对于稀疏矩阵,非零元可以用三元组表示, 整个稀疏矩阵可以表示为所有非零元的三元组所 构成的线性表。例如:
数据结构 5数组和广义表A

1 Status Locate(Array A,va_list ap,int &off) 2{ 3 //若ap指示的各下标值合法,则求出该元素在A中,相对地
址off
4 off=0; 5 for(i=0;i<A.dim;++i) 6 { 7 ind=va_arg(ap,int); 8 if(ind<0||ind>A.bounds[i]) return OVERFLOW; 9 off+=A.constants[i] *ind; 10 } 11 return OK; 12 }
行数 总列数,即 第2维长度 元素个数
ij
补充:计算二维数组元素地址的通式
设一般的二维数组是A[c1..d1, c2..d2],这里c1,c2不一定是0。
单个元素 长度
二维数组列优先存储的通式为: LOC(aij)=LOC(ac1,c2)+[(j-c2)*(d1-c1+1)+i-c1)]*L
6
例1〖软考题〗:一个二维数组A[1..6, 0..7],每个数组元素
16
5.4
1、定义:
广义表的定义
广义表是线性表的推广,也称为列表(lists) 记为: LS = ( a1 , a2 , ……, an ) 广义表名 表头(Head) 表尾 (Tail) n是表长
在广义表中约定:
① 第一个元素是表头,而其余元素组成的表称为表尾; ② 用小写字母表示原子类型,用大写字母表示列表。
13
1 Status Value(Array A,ElemType &e,…){ 2 //A是n维数组,e为元素变量,随后是n个下标值,若各下
标不超界,则e赋值为所指定的A的元素值,即将指定元素值 读到e变量中。
数据结构递归与广义表

第5章递归与广义表一、复习要点本章主要讨论递归过程和广义表。
一个递归的定义可以用递归的过程计算,一个递归的数据结构可以用递归的过程实现它的各种操作,一个递归问题也可以用递归的过程求解。
因此,递归算法的设计是必须掌握的基本功。
递归算法的一般形式:void p ( 参数表) {if( 递归结束条件)可直接求解步骤;基本项else p( 较小的参数);归纳项}在设计递归算法时,可以先考虑在什么条件下可以直接求解。
如果可以直接求解,考虑求解的步骤,设计基本项;如果不能直接求解,考虑是否可以把问题规模缩小求解,设计归纳项,从而给出递归求解的算法。
必须通过多个递归过程的事例,理解递归。
但需要说明的是,递归过程在时间方面是低效的。
广义表是一种表,它的特点是允许表中套表。
因此,它不一定是线性结构。
它可以是复杂的非线性结构,甚至允许递归。
可以用多重链表定义广义表。
在讨论广义表时,特别注意递归在广义表操作实现中的应用。
本章复习的要点:1、基本知识点要求理解递归的概念:什么是递归?递归的定义、递归的数据结构、递归问题以及递归问题的递归求解方法。
理解递归过程的机制与利用递归工作栈实现递归的方法。
通过迷宫问题,理解递归解法,从而掌握利用栈如何实现递归问题的非递归解法。
在广义表方面,要求理解广义表的概念,广义表的几个性质,用图表示广义表的方法,广义表操作的使用,广义表存储结构的实现,广义表的访问算法,以及广义表的递归算法。
2、算法设计求解汉诺塔问题,掌握分治法的解题思路。
求解迷宫问题、八皇后问题,掌握回溯法的解题思路。
对比单链表的递归解法和非递归解法,掌握单向递归问题的迭代解法。
计算广义表结点个数,广义表深度,广义表长度的递归算法。
输出广义表各个原子所在深度的非递归算法。
判断两个广义表相等的递归算法。
广义表的按深度方向遍历和按层次(广度)方向遍历的递归算法。
使用栈的广义表的按深度方向遍历的非递归算法。
递归的广义表的删除算法二、难点与重点1、递归:递归的定义、递归的数据结构、递归问题用递归过程求解链表是递归的数据结构,可用递归过程求解有关链表的问题2、递归实现时栈的应用递归的分层(树形)表示:递归树递归深度(递归树的深度)与递归工作栈的关系单向递归与尾递归的迭代实现3、广义表:广义表定义、长度、深度、表头、表尾用图形表示广义表的存储结构广义表的递归算法,包括复制、求深度、求长度、删除等算法三、教材中习题的解析5-1 已知A[n]为整数数组,试写出实现下列运算的递归算法:(1) 求数组A中的最大整数。
《数据结构》习题集:第5章

第5章数组与广义表一、选择题1.在以下讲述中,正确的是(B )。
A、线性表的线性存储结构优于链表存储结构B、二维数组是其数据元素为线性表的线性表C、栈的操作方式是先进先出D、队列的操作方式是先进后出2.若采用三元组压缩技术存储稀疏矩阵,只要把每个元素的行下标和列下标互换,就完成了对该矩阵的转置运算,这种观点(A )。
A、正确B、错误3.二维数组SA 中,每个元素的长度为3 个字节,行下标I 从0 到7,列下标J 从0 到9,从首地址SA 开始连续存放在存储器内,该数组按列存放时,元素A[4][7]的起始地址为(B)。
A、SA+141B、SA+180C、SA+222D、SA+2254.数组SA 中,每个元素的长度为3 个字节,行下标I 从0 到7,列下标J 从0 到9,从首地址SA 开始连续存放在存储器内,存放该数组至少需要的字节数是( C )。
A、80B、100C、240D、2705.常对数组进行的两种基本操作是(B )。
A、建立与删除B、索引和修改C、查找和修改D、查找和索引6.将一个A[15][15]的下三角矩阵(第一个元素为A[0][0]),按行优先存入一维数组B[120]中,A 中元素A[6][5]在B 数组中的位置K 为( B )。
A、19B、26C、21D、157.若广义表A 满足Head(A)=Tail(A),则A 为(B )。
A、()B、(())C、((),())D、((),(),())8.广义表((a),a)的表头是( C ),表尾是(C )。
A、aB、bC、(a)D、((a))9.广义表((a,b),c,d)的表头是( C ),表尾是(D )。
A、aB、bC、(a,b)D、(c,d)10.广义表((a))的表头是( B ),表尾是(C )。
A、aB、(a)C、()D、((a))11.广义表(a,b,c,d)的表头是(A ),表尾是(D )。
A、aB、(a)C、(a,b)D、(b,c,d)12.广义表((a,b,c,d))的表头是(C ),表尾是(B )。
《数据结构与算法》第五章-数组和广义表学习指导材料

《数据结构与算法》第五章数组和广义表本章介绍的数组与广义表可视为线性表的推广,其特点是数据元素仍然是一个表。
本章讨论多维数组的逻辑结构和存储结构、特殊矩阵、矩阵的压缩存储、广义表的逻辑结构和存储结构等。
5.1 多维数组5.1.1 数组的逻辑结构数组是我们很熟悉的一种数据结构,它可以看作线性表的推广。
数组作为一种数据结构其特点是结构中的元素本身可以是具有某种结构的数据,但属于同一数据类型,比如:一维数组可以看作一个线性表,二维数组可以看作“数据元素是一维数组”的一维数组,三维数组可以看作“数据元素是二维数组”的一维数组,依此类推。
图5.1是一个m行n列的二维数组。
5.1.2 数组的内存映象现在来讨论数组在计算机中的存储表示。
通常,数组在内存被映象为向量,即用向量作为数组的一种存储结构,这是因为内存的地址空间是一维的,数组的行列固定后,通过一个映象函数,则可根据数组元素的下标得到它的存储地址。
对于一维数组按下标顺序分配即可。
对多维数组分配时,要把它的元素映象存储在一维存储器中,一般有两种存储方式:一是以行为主序(或先行后列)的顺序存放,如BASIC、PASCAL、COBOL、C等程序设计语言中用的是以行为主的顺序分配,即一行分配完了接着分配下一行。
另一种是以列为主序(先列后行)的顺序存放,如FORTRAN语言中,用的是以列为主序的分配顺序,即一列一列地分配。
以行为主序的分配规律是:最右边的下标先变化,即最右下标从小到大,循环一遍后,右边第二个下标再变,…,从右向左,最后是左下标。
以列为主序分配的规律恰好相反:最左边的下标先变化,即最左下标从小到大,循环一遍后,左边第二个下标再变,…,从左向右,最后是右下标。
例如一个2×3二维数组,逻辑结构可以用图5.2表示。
以行为主序的内存映象如图5.3(a)所示。
分配顺序为:a11 ,a12 ,a13 ,a21 ,a22,a23 ; 以列为主序的分配顺序为:a11 ,a21 ,a12 ,a22,a13 ,a23 ; 它的内存映象如图5.3(b)所示。
《数据结构(Python语言描述)》第5章 广义表

广义表是由n个类型相同的数据元素(a1、a2、……、an)组成的有限序列。广义表的元素可以是单个 元素,也可以是一个广义表。通常广义表记作:
GL=(a1,a2,…,an) 广义表有两种数据元素,分别是原子和子表,因此需要两种结构的节点,一种是表节点,用来表 示子表,如图5-1所示;一种是原子节点,用来表示原子,如图5-2所示。
OPTION
在广义表GL中,如果ai也是一个 广义表表,则称ai为广义表GL的 子表。
03 表头
OPTION
在广义表中GL中,a1如果不为空, 则称a1为广义表的表头。
04 表尾
OPTION
在广义表GL中,除了表头a1的其余 元素组成的表称为表尾。
05 深度
OPTION
广义表GL中括号嵌套的最大层数。
图5-3 广义表表节点
表节点由三个域组成:标志域tag,指向表头节点的指针域ph,指向表尾节 点的指针域pt。表节点的标志域tag=1。
5.3 存储结构
7
图5-4 广义表原子节点
原子节点由两个域组成:标志域tag,值域atom。原子节点的标志域tag=0。
节点的定义:
class Node:
def __init__(self, ph, pt, tag, atom):
表节点由三个域组成,即标志域tag、指向表头节点的指针域ph、指向表尾节点的指针域pt。表节点 的标志域tag=1。
原子节点由两个域组成,即标志域tag、值域atom。原子节点的标志域tag=0。
5.2 基本用语
4
01 原子
OPTION
在广义表GL中,如果ai为单个元 素,则称ai称为原子
02 子表
数据结构第五章

5.3.1 特殊矩阵
是指非零元素或零元素的分布有一定规律的矩阵。
1、对称矩阵 在一个n阶方阵A中,若元素满足下述性质: aij = aji 0≦i,j≦n-1 则称A为对称矩阵。
对称矩阵中的元素关于主对角线对称,故只 要存储矩阵中上三角或下三角中的元素,这样, 能节约近一半的存储空间。
2013-7-25 第4章 18
5.3 矩阵的压缩存储
在科学与工程计算问题中,矩阵是一种常用 的数学对象,在高级语言编制程序时,常将 一个矩阵描述为一个二维数组。 当矩阵中的非零元素呈某种规律分布或者矩 阵中出现大量的零元素的情况下,会占用许 多单元去存储重复的非零元素或零元素,这 对高阶矩阵会造成极大的浪费。 为了节省存储空间,我们可以对这类矩阵进 行压缩存储:
5.2 数组的顺序表示和实现 由于计算机的内存结构是一维的, 因此用一维内存来表示多维数组,就必 须按某种次序将数组元素排成一列序列 ,然后将这个线性序列存放在存储器中 。 又由于对数组一般不做插入和删除 操作,也就是说,数组一旦建立,结构 中的元素个数和元素间的关系就不再发 生变化。因此,一般都是采用顺序存储 的方法来表示数组。
即为多个相同的非零元素只分配一个存储空间; 对零元素不分配空间。
课堂讨论: 1. 什么是压缩存储? 若多个数据元素的值都相同,则只分配一个元素值的 存储空间,且零元素不占存储空间。 2. 所有二维数组(矩阵)都能压缩吗? 未必,要看矩阵是否具备以上压缩条件。 3. 什么样的矩阵具备以上压缩条件? 一些特殊矩阵,如:对称矩阵,对角矩阵,三角矩阵, 稀疏矩阵等。 4. 什么叫稀疏矩阵? 矩阵中非零元素的个数较少(一般小于5%)
通常有两种顺序存储方式:
⑴行优先顺序——将数组元素按行排列,第i+1个行 向量紧接在第i个行向量后面。以二维数组为例,按 行优先顺序存储的线性序列为: a11,a12,…,a1n,a21,a22,…a2n,……,am1,am2,…,amn 在PASCAL、C语言中,数组就是按行优先顺序存 储的。 ⑵列优先顺序——将数组元素按列向量排列,第j+1 个列向量紧接在第j个列向量之后,A的m*n个元素按 列优先顺序存储的线性序列为: a11,a21,…,am1,a12,a22,…am2,……,an1,an2,…,anm 在FORTRAN语言中,数组就是按列优先顺序存储的。
数据结构5.3_广义表的定义和存储结构

数据结构5.3_⼴义表的定义和存储结构⼴义表定义:⼴义表(Lists,⼜称列表)是⼀种⾮线性的数据结构,是线性表的⼀种推⼴。
即⼴义表中放松对表元素的原⼦限制,容许它们具有其⾃⾝结构。
⼀个⼴义表是n(n≥0)个元素的⼀个序列,若n=0时则称为空表。
GL=(a1,a2,…,ai,…,an)其中n表⽰⼴义表的长度,即⼴义表中所含元素的个数,n≥0。
如果ai是单个数据元素,则ai是⼴义表GL的原⼦;如果ai是⼀个⼴义表,则ai是⼴义表GL的⼦表。
习惯上⽤⼤写表⽰⼴义表的名称;⽤⼩写字母表⽰原⼦。
当⼴义表⾮空时,称第⼀个元素a1为GL的表头(Head),称其余元素组成的表(a2,a3,...an)是GL的表尾(Tail)。
可以发现上述⼴义表的定义描述时,⼜⽤到了⼴义表的概念;⼴义表的存储结构:⼴义表中的数据元素可以具有不同的结构(或是原⼦,或是列表)。
因此难以⽤顺序存储结构表⽰,通常采⽤链式存储结构。
每个数据元素可⽤⼀个结点表⽰。
如何设定结点的结构?由于列表中的数据元素可能为原⼦或列表。
因此需要两种结构的结点:⼀种是表结点⽤于表⽰列表,⼀种是原⼦结点⽤于表⽰原⼦;若列表不空,则可以分解成表头和表尾;⼀个表结点可以由3个域组成:标志域(标识是表还是原⼦)、指⽰表头的指针域、指⽰表尾的指针域;对于原⼦结点只需要2个域:标志域、值域;--------⼴义表的头尾链表存储表⽰--------typedef enum {ATOM, LIST} ElemTag; //ATOM==0 原⼦; LIST==1 ⼦表typedef struct GLNode{ ElemTag tag; //公共部分,⽤于区分原⼦结点和表结点 union{ //原⼦结点和表结点的联合部分 AtomType atom; //atom是原⼦结点的值域, struct{ struct GLNode *hp *tp}ptr; //ptr是表结点的指针域,ptr.hp和ptr.tp分别指向表头和表尾 };} *GList; //⼴义表类型--------⼴义表的扩展线性链表存储表⽰--------typedef enum {ATOM, LIST}ElemTag;typedef struct GLNode{ ElemTag tag; union{ AtomType atom; struct GLNode *hp; } struct GLNode *tp;} *GList;相关链接:。
第5章广义表

数据结构
else h=NULL; ch=*(*s); (*s)++; if(h!=NULL) if(ch==',') h->link =creat_GL(s); else h->link=NULL; return(h); }
该算法的时间复杂度为O(n)。
数据结构
2.输出广义表prn_GL(p) 对于广义表的表头结点p,若为表结点,输出空表或递归 输出子表的内容,否则,输出元素值;若当前的结点还有 后续结点,则递归输出后续表的内容。 下面的函数把按链接存储的广义表以字符串形式输出。 void prn_GL(NODE *p) { if(p!=NULL) { if(p->tag==1) { printf("("); if(p->dd.sublist ==NULL) printf(" "); 数据结构
5.取表尾运算tail .取表尾运算 若广义表LS=(a1 ,a2 ,…,an),则tail(LS)=(a2 ,a3 ,…, an)。 即取表尾运算得到的结果是除表头以外的所有元素,取 表尾运算得到的结果一定是一个子表。 值得注意的是广义表( )和(())是不同的,前者为空表,长 度为0,后者的长度为1,可得到表头、表尾均为空表, 即head((( )))=( ),tail((( )))=( )。 数据结构
四、几个运算的调用
下列主函数的功能是:创建带表头结点链式存储的广义表 然后复制一个新的广义表,并把广义表按字符串的方式 输出. main() { NODE *hd,*hc; char s[100],*p; p=gets(s); hd=creat_GL(&p); hc=copy_GL(hd); printf("copy after:"); prn_GL(hc); }
数据结构第五章数组和广义表

数据结构第五章数组和广义表(总6页)--本页仅作为文档封面,使用时请直接删除即可----内页可以根据需求调整合适字体及大小--第五章数组和广义表:习题习题一、选择题1.假设以行序为主序存储二维数组A[1..100,1..100],设每个数据元素占两个存储单元,基地址为10,则LOC(A[5,5])=( )。
A. 808B. 818C. 1010D. 10202.同一数组中的元素( )。
A. 长度可以不同 B.不限 C.类型相同 D. 长度不限3.二维数组A的元素都是6个字符组成的串,行下标i的范围从0到8,列下标j的范圈从1到10。
从供选择的答案中选出应填入下列关于数组存储叙述中( )内的正确答案。
(1)存放A至少需要( )个字节。
(2)A的第8列和第5行共占( )个字节。
(3)若A按行存放,元素A[8]【5]的起始地址与A按列存放时的元素( )的起始地址一致。
供选择的答案:(1)A. 90 B. 180 C. 240 D. 270(2) A. 108 B. 114 C. 54 D. 60(3)[8][5] B. A[3][10] [5][8] [O][9]4.数组与一般线性表的区别主要是( )。
A.存储方面B.元素类型方面C.逻辑结构方面D.不能进行插入和删除运算5.设二维数组A[1..m,1..n]按行存储在数组B[1..m×n]中,则二维数组元素A[i,j]在一维数组B中的下标为( )。
A. (i-l)×n+jB. (i-l)×n+j-lC.i×(j-l) D. j×m+i-l6.所谓稀疏矩阵指的是( )。
A.零元素个数较多的矩阵B.零元素个数占矩阵元素中总个数一半的矩阵C.零元素个数远远多于非零元素个数且分布没有规律的矩阵D.包含有零元素的矩阵7.对稀疏矩阵进行压缩存储的目的是( )。
A.便于进行矩阵运算B.便于输入和输出C.节省存储空间D. 降低运算的时间复杂度8.稀疏矩阵一般的压缩存储方法有两种,即( )。
数据结构第五章数组和广义表

第五章数组和广义表:习题习题一、选择题1.假设以行序为主序存储二维数组A[1..100,1..100],设每个数据元素占两个存储单元,基地址为10,则LOC(A[5,5])=( )。
A. 808B. 818C. 1010D. 10202.同一数组中的元素( )。
A. 长度可以不同 B.不限 C.类型相同 D. 长度不限3.二维数组A的元素都是6个字符组成的串,行下标i的范围从0到8,列下标j的范圈从1到10。
从供选择的答案中选出应填入下列关于数组存储叙述中( )内的正确答案。
(1)存放A至少需要( )个字节。
(2)A的第8列和第5行共占( )个字节。
(3)若A按行存放,元素A[8]【5]的起始地址与A按列存放时的元素( )的起始地址一致。
供选择的答案:(1)A. 90 B. 180 C. 240 D. 270(2) A. 108 B. 114 C. 54 D. 60(3)[8][5] B. A[3][10] [5][8] [O][9]4.数组与一般线性表的区别主要是( )。
A.存储方面B.元素类型方面C.逻辑结构方面D.不能进行插入和删除运算5.设二维数组A[1..m,1..n]按行存储在数组B[1..m×n]中,则二维数组元素A[i,j]在一维数组B中的下标为( )。
A. (i-l)×n+jB. (i-l)×n+j-lC.i×(j-l) D. j×m+i-l6.所谓稀疏矩阵指的是( )。
A.零元素个数较多的矩阵B.零元素个数占矩阵元素中总个数一半的矩阵C.零元素个数远远多于非零元素个数且分布没有规律的矩阵D.包含有零元素的矩阵7.对稀疏矩阵进行压缩存储的目的是( )。
A.便于进行矩阵运算B.便于输入和输出C.节省存储空间D. 降低运算的时间复杂度8.稀疏矩阵一般的压缩存储方法有两种,即( )。
A.二维数组和三维数组B.三元组和散列C.三元组和十字链表D.散列和十字链表9.有一个100×90的稀疏矩阵,非0元素有10个,设每个整型数占两字节,则用三元组表示该矩阵时,所需的字节数是( )。
大学数据结构课件--第5章 数组和广义表

a 32 a 33 a 34 0 0
a 43 a 44 a 45 0
a 54 a 55 a 56 a 65 a 66
5.3.2 稀疏矩阵
稀疏矩阵的存储:如何表示非零元素的位置信息 1. 三元组表:每个元素用一个三元组(i,j,v)来表示。 i j v
0 1 6 1 1 6 2 3 8 12 9
2
3 4 5 6 7 8
2
5.2 数组的顺序表示和实现
a00 a00 a10 a01 存储单元是一维结构,而数组是个多维结构 , …… …… 则用一组连续存储单元存放数组的数据元素就有 am-1,0 a0,n-1 个次序约定问题。 a01 a10
a11
……
a11
……
二维数组可有两种存储方式: am-1,1 a1,n-1
……
K=
i*n-i(i-1)/2+j-i n(n+1)/2
当 i≤j 当i>j
0 a11 ... a1n-1 ... ... ... ... 0 0 0 an-1n-1
当i ≤ j时,a[i][j]是非零元素, a[i][j]前面有i行,共有n+(n-1)+(n-2)+…(n-(i-1))
=i(n+[n-(i-1)])/2=i*n-i(i-1)/2个元素,a[i][j]前面有j列,共j-i个非零元素,
A m× n
( a10 a11 … a1,n-1 )
=
注:
( … … …… ) ( am-1,0 am-1,2 … am-1,n-1 ) ( ( ( (
① 数组中的元素都具有统一的类型; ② 数组元素的下标一般都具有固定的上界和下界,即数组一旦 被定义,它的维数和维界就不再发生改变; ③ 数组的基本操作简单:初始化、销毁、存取元素和修改元素值
数据结构课后习题答案第五章数组与广义表

第五章数组与广义表一、假设有二维数组A6*8,每个元素用相邻的6个字节存储,存储器按字节编址。
已知A的起始存储位置(基地址)为1000。
计算:1、数组A的体积(即存储量);2、数组A的最后一个元素a57的第一个字节的地址;3、按行存储时,元素a14的第一个字节的地址;4、按列存储时,元素a47的第一个字节的地址;答案:1、(6*8)*6=2882、loc(a57)=1000+(5*8+7)*6=1282或=1000+(288-6)=12823、loc(a14)=1000+(1*8+4)*6=10724、loc(a47)=1000+(7*6+4)*6=1276二、假设按低下标(行优先)优先存储整数数组A9*3*5*8时第一个元素的字节地址是100,每个整数占四个字节。
问下列元素的存储地址是什么?(1)a0000(2)a1111(3)a3125 (4)a8247答案:(1)100(2)loc(a1111)=100+(1*3*5*8+1*5*8+1*8+1)*4=776(3) loc(a3125)=100+(3*3*5*8+1*5*8+2*8+5)*4=1784(4) loc(a8247)=100+(8*3*5*8+2*5*8+4*8+7)*4=4416五、设有一个上三角矩阵(aij)n*n,将其上三角元素逐行存于数组B[m]中,(m 充分大),使得B[k]=aij且k=f1(i)+f2(j)+c。
试推导出函数f1,f2和常数C(要求f1和f2中不含常数项)。
答:K=n+(n-1)+(n-2)+…..+(n-(i-1)+1)+j-i=(i-1)(n+(n-i+2))/2+j-i所以f1(i)=(n+1/2)i-1/2i2f2(j)=jc=-(n+1)九、已知A为稀疏矩阵,试从空间和时间角度比较采用两种不同的存储结构(二维数组和三元组表)完成∑aii运算的优缺点。
(对角线求和)解:1、二维数组For(i=1;i<=n;i++)S=s+a[i][i];时间复杂度:O(n)2、for(i=1;i<=m.tu;i++)If(a.data[k].i==a.data[k].j) s=s+a.data[k].value;时间复杂度:O(n2)二十一、当稀疏矩阵A和B均以三元组表作为存储结构时,试写出矩阵相加的算法,其结果存放在三元组表C中。
数据结构数组和广义表

数据结构05数组与广义表数组与广义表可以看做是线性表地扩展,即数组与广义表地数据元素本身也是一种数据结构。
5.1 数组地基本概念5.2 数组地存储结构5.3 矩阵地压缩存储5.4 广义表地基本概念数组是由相同类型地一组数据元素组成地一个有限序列。
其数据元素通常也称为数组元素。
数组地每个数据元素都有一个序号,称为下标。
可以通过数组下标访问数据元素。
数据元素受n(n≥1)个线性关系地约束,每个数据元素在n个线性关系地序号 i1,i2,…,in称为该数据元素地下标,并称该数组为n维数组。
如下图是一个m行,n列地二维数组A矩阵任何一个元素都有两个下标,一个为行号,另一个为列号。
如aij表示第i行j列地数据元素。
数组也是一种线性数据结构,它可以看成是线性表地一种扩充。
一维数组可以看作是一个线性表,二维数组可以看作数据元素是一维数组(或线性表)地线性表,其一行或一列就是一个一维数组地数据元素。
如上例地二维数组既可表示成一个行向量地线性表: A1=(a11,a12,···,a1n)A2=(a21,a22, ···,a2n)A=(A1,A2, ···,Am) ············Am=(am1,am2, ···,amn)也可表示成一个列向量地线性表:B1=(a11,a21,···,am1)B2=(a12,a22, ···,am2)A=(B1,B2, ···,Bm) ············Bn=(a1n,a2n, ···,amn)数组地每个数据元素都与一组唯一地下标值对应。
数据结构第五章 数组和广义表

5.3.1
特殊矩阵
1、对称矩阵 在一个n阶方阵A中,若元素满足下述性质: aij = aji 1≤i,j≤n 则称A为对称矩阵。 a11 1 5 1 3 7 a21 a 22 5 0 8 0 0 a31 a32 a33 1 8 9 2 6 ……………….. 3 0 2 5 1 an 1 a n 2 a n 3 …a n n 7 0 6 1 3
第5章
数组和广义表
5.1 数组的定义
5.2 数组的顺序表示和实现
5.3 矩阵的压缩存储
5.3.1 特殊矩阵
5.3.2 稀疏矩阵
5.4 广义表的定义
5.1 数组的定义
数组-----线性表的扩展 A =(a0,a1,a2,…,an-1)
a00 a10 ┇ Am×n= ai0 ┇ am-1,0 a01 … a0j … a11 … a1j … ┇ ai2 … aij … ┇ am-1,2 … am-1,j … a0,n-1 a1,n-1 ai,n-1 am-1,n-1 α0 α1 ┇ Am×n= α i ┇ α m-1
Assign( &A, e, index1, ..., indexn) 赋值操作 初始条件:A是n维数组,e为元素变量,随后是n个下标值。 操作结果:若下标不超界,则将e的值赋给所指定的A的元 素,并返回OK。 对于数组来说一旦维数确定了,每个元素的下标确定了, 那么整个数组就确定了,这样的一个数组结构除了能改变 某元素的值,其他的不能再改变。
5.2 数组的顺序表示和实现
数组类型特点: 1) 只有引用型操作,没有加工型操作; 2) 数组是多维的结构,而存储空间是一个一维的结构。 有两种顺序映象的方式。
有两种顺序映像方法: 1)以行序为主序(行优先,先行后列):先存储行号较小 的元素,行号相同者先存储列号较小的元素;
数据结构讲义第5章-数组和广义表

5.4 广义表
5)若广义表不空,则可分成表头和表尾,反之,一对表头和表尾 可唯一确定广义表 对非空广义表:称第一个元素为L的表头,其余元素组成的表称 为LS的表尾; B = (a,(b,c,d)) 表头:a 表尾 ((b,c,d)) 即 HEAD(B)=a, C = (e) D = (A,B,C,f ) 表头:e 表尾 ( ) TAIL(B)=((b,c,d)),
5.4 广义表
4)下面是一些广义表的例子; A = ( ) 空表,表长为0; B = (a,(b,c,d)) B的表长为2,两个元素分别为 a 和子表(b,c,d); C = (e) C中只有一个元素e,表长为1; D = (A,B,C,f ) D 的表长为4,它的前三个元素 A B C 广义表, 4 A,B,C , 第四个是单元素; E=( a ,E ) 递归表.
以二维数组为例:二维数组中的每个元素都受两个线性关 系的约束即行关系和列关系,在每个关系中,每个元素aij 都有且仅有一个直接前趋,都有且仅有一个直接后继. 在行关系中 aij直接前趋是 aij直接后继是 在列关系中 aij直接前趋是 aij直接后继是
a00 a01 a10 a11
a0 n-1 a1 n-1
a11 a21 ┇ a12 a22 ┇ ai2 ┇ … amj … amn … aij … ain … … a1j a2j … … a1n a2n β1 β2 ┇ βi ┇ βm
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
if(i<n){ hstr=str.substr(1,i-2); str="("+str.substr(i,n-i); } else{ hstr=str.substr(1,n-2); str=""; } return hstr; }
何谓"递归函数 ? 何谓 递归函数"? 递归函数
一个含直接或间接调用本函数语句的函数被 称之为递归函数,它必须满足以下两个条件: 称之为递归函数,它必须满足以下两个条件: 在每一次调用自己时,必须是(在某种意义 ①在每一次调用自己时,必须是 在某种意义 更接近于解; 上)更接近于解; 更接近于解 函数中必须有一个终止处理或计算的准则。 ②函数中必须有一个终止处理或计算的准则。
的存储结构。 例:广义表 L=(a,(x,y),((z))) 的存储结构。
可由对L进行表头和表尾的分析得到 若列表不空 可由对 进行表头和表尾的分析得到--若列表不空, 进行表头和表尾的分析得到 若列表不空, 则可分解成表头和表尾(采用头尾链表存储结构)。 则可分解成表头和表尾(采用头尾链表存储结构)。 分析: 分析: ①L为一非空列表 为一非空列表
// 将非空串 分割成两部分: 将非空串str分割成两部分 分割成两部分: // hsub为最外层第一个 之前的子串,str为之后的子串 为最外层第一个','之前的子串 为最外层第一个 之前的子串, 为之后的子串 string sever(string& str) { int n,k,i; // k记录尚未配对的左括号个数 记录尚未配对的左括号个数 string ch,hstr; n=str.length(); for(i=0,k=-1; i<n&&(ch!=","||k!=0); ++i) { // 搜索最外层的第一个逗号 ch=str.substr(i,1); //从第 个位置起,取1个字符 从第i个位置起 从第 个位置起, 个字符 if(ch=="(") ++k; else if(ch==")") --k; }
⑷ 建立广义表 以广义表字符串S建立广义表 建立广义表。 以广义表字符串 建立广义表。 从前面的讨论可知, 从前面的讨论可知,非空广义表可分解成表头和表 尾两个部分。建表时,可分别建立( 尾两个部分。建表时,可分别建立(分解为两个子 问题): 问题): 表头有两种情况,为单原子或为列表, 两种情况 表头有两种情况,为单原子或为列表,当为列表时 与原问题相同; 与原问题相同; 表尾必为列表,与原问题相同。 必为列表 表尾必为列表,与原问题相同。 函数的功能 设string sever(string& S )函数的功能为: 函数的功能为 从广义表字符串S中提取表头串返回 并将S置成表 中提取表头串返回, 从广义表字符串 中提取表头串返回,并将 置成表 尾串。 尾串。
并且为了在存储结构中便于分辩原子和子表, 并且为了在存储结构中便于分辩原子和子表,令表 示广义表的链表中的结点为"异构 结点,如图所示, 异构"结点 示广义表的链表中的结点为 异构 结点,如图所示, 结点中设有一个"标志域 标志域tag", 并约定 tag=0 表示 结点中设有一个 标志域 , 原子结点, 表示表结点。 原子结点,tag=1 表示表结点。原子结点中的 data 域存储原子, 域存储原子,表结点中指针域的两个值分别指向表 头和表尾。 头和表尾。
5.2.2 广义表的头尾链表存储表示
glist.h #include <iostream> #include <string> using namespace std; enum ElemTag {ATOM,LIST}; typedef char AtomType;
struct GLNode{ ElemTag tag; union { //匿名共用体 匿名共用体 AtomType atom; struct { GLNode *hp,*tp; } ptr; }; }; typedef GLNode* GList;
为广义表的第i个元素 广义表LS可表示为 个元素, 可表示为: 设ai为广义表的第 个元素,广义表 可表示为: LS=(a1,a2,…, an) ( , 其中: 其中: 广义表的名字; ①LS——广义表的名字; 广义表的名字 广义表的长度; ②n——广义表的长度; 广义表的长度 或者是单元素 (小写) ③ ai--表中的元素 ; 或者是表元素 (大写) 空表; ④n=0 空表; 当广义表非空时, 表头( ),其余元素组 ⑤当广义表非空时,称a1为表头(head),其余元素组 ), 成的表( 表尾( ); 成的表(a2,a3, …, an)为表尾(tail); , 广义表的抽象数据类型: 广义表的抽象数据类型:P107
⑶ 求广义表的深度 int getDepth(GList L) //采用头尾链表存储结构,求广义表 的深度 采用头尾链表存储结构, 采用头尾链表存储结构 求广义表L的深度 { int max=0,dep; GList p; if(!L) return 1; //空表深度为 空表深度为1 空表深度为 if(L->tag==ATOM) return 0; //原子深度为 原子深度为0 原子深度为 for(p=L; p; p=p->ptr.tp){ dep=getDepth(p->ptr.hp); //求以 求以p->a.ptr.hp为头指针的子表深度 求以 为头指针的子表深度 if(dep>max) max=dep; } return max+1; // 非空表的深度是各元素的深度的最大值加 非空表的深度是各元素的深度的最大值加1 }
5.1.2 举例
分别用圆圈和方框表示表(表元素) 分别用圆圈和方框表示表(表元素)和单元素 ①A=() () 空表,其长度为零。 空表,其长度为零。
②B=(e) ( ) B中只有一个单元素,长度为 ,表头为 ,表尾为 中只有一个单元素, 中只有一个单元素 长度为1,表头为'e', 空。
,(b, , )) ③C=(a,( ,c,d)) ( ,( 长度为2,表头为‘ ,表尾为子表(( ((b, , 长度为 ,表头为‘a’,表尾为子表(( ,c, d))。 ))。
的表头为原子a ②L的表头为原子 的表头为原子
的表尾为列表((x,y),((z))) ③L的表尾为列表 的表尾为列表
的表头为列表(x,y) ④((x,y),((z)))的表头为列表 的表头为列表
其余分析同上。 其余分析同上。
5.2 广义表操作的实现
基于广义表是递归定义的结构, 基于广义表是递归定义的结构,因此实现广 义表操作的算法均为递归函数。 义表操作的算法均为递归函数。
5.1.3广义表的几个性质 广义表的几个性质
①有次序性: 有次序性: 广义表中的数据元素有固定的相对次序。 广义表中的数据元素有固定的相对次序。 线性排列 --线性表的推广 线性表的推广 层次结构 --树的推广 树的推广 有长度: ②有长度: 广义表的长度定义为最外层 最外层括弧中包含的数 广义表的长度定义为最外层括弧中包含的数 据元素个数。 据元素个数。 表元素个数一定,不能无限,可以是空表。 表元素个数一定,不能无限,可以是空表。
第5章 广义表 章
5.1 广义表的定义 5.2 广义表操作的实现
5.1 广义表的定义
5.1.1 定义
广义表( 广义表(Lists)简称表,它是线性表的推广。 )简称表,它是线性表的推广。 一个广义表是n( 一个广义表是 (n≥0)个元素的序列,当 )个元素的序列, n=0时称为空表。在一个非空的广义表中,其 时称为空表。 时称为空表 在一个非空的广义表中, 元素可以是某一确定类型的对象( 元素可以是某一确定类型的对象(这种元素 被称作单元素),也可以是由单元素构成的 单元素), 被称作单元素),也可以是由单元素构成的 这种元素可相对地被称作子表 子表或 表(这种元素可相对地被称作子表或表元 )。显然 广义表的定义是递归的, 显然, 素)。显然,广义表的定义是递归的,广义 表是一种递归的数据结构。 表是一种递归的数据结构。
5.1.4 广义表的存储结构
由于广义表中的数据元素可以是原子, 由于广义表中的数据元素可以是原子,也可 以是广义表,显然难以用顺序存储结构表示。 以是广义表,显然难以用顺序存储结构表示。 由于列表中的数据元素可能为原子或列表, 由于列表中的数据元素可能为原子或列表, 由此需要两种结构的结点:一种是表结点, 由此需要两种结构的结点:一种是表结点, 用以表示列表;一种是原子结点, 用以表示列表;一种是原子结点,用以表示 原子。 原子。
④D=(A,B,C) ( , , ) 长度为3,表头为A, 表尾为( , )。 长度为 ,表头为 表尾为(B,C)。
⑤E=(a,E) ( , ) 长度为2,表头为a,表尾为( ) 表头为 表头为E, 长度为 ,表头为 ,表尾为(E)--表头为 ,表尾为 ()。E相当于无穷表 相当于无穷表( ,( ,(a,( ,( ,(…))))。 ()。 相当于无穷表(a,( (a,( ))))。
void initGList(GList& L); // 创建空的广义表 创建空的广义表L int getLength(GList L); int getDepth(GList L); void creatGList(GList& L,string s); void printGList(GList& L,int k=0);
tag=0 atom
原子结点
tag=1
ptr---表结点的指针域 hp tp
表结点
广义表的头尾链表存储表示: 广义表的头尾链表存储表示:
enum ElemTag {ATOM,LIST}; typedef char AtomType; struct GLNode{ ElemTag tag; union { AtomType atom; struct { GLNode *hp,*tp; } ptr; }; }; typedef GLNode* GList;