广义表
第5章 广义表

12
例:求下列广义表操作的结果(严题集5.10②) (k, p, h) ; 1. GetTail【(b, k, p, h)】=
2. GetHead【( (a,b), (c,d) )】= 3. GetTail【( (a,b), (c,d) )】=
(c,d)
((c,d)) ;
;
4. GetTail【 GetHead【((a,b),(c,d))】】=(b) ; 5. GetTail【(e)】= 6. GetHead 【 ( ( ) )】= 7. GetTail【 ( ( ) ) 】= () ; . .
讨论:广义表与线性表的区别和联系? 广义表中元素既可以是原子类型,也可以是列表; 当每个元素都为原子且类型相同时,就是线性表。
3
广义表是递归定义的线性结构,
LS = ( 1, 2, , n ) 其中:i 或为原子 或为广义表
例如: A = ( ) F = (d, (e)) D = ((a,(b,c)), F) C = (A, D, F) B = (a, B) = (a, (a, (a, , ) ) )
13
(a,b)
()
()
5.5 广义表的存储结构
由于广义表的元素可以是不同结构(原子或列表),难以用 顺序存储结构表示 ,通常用链式结构,每个元素用一个结 点表示。 注意:列表的“元素”还可以是列表,所以结点可能有两种形 式 1.原子结点:表示原子,可设2个域或3个域,依习惯而选。 法1:标志域,数值域 tag=0 标志域 value 数值域 法2:标志域、值域、表尾指针 tag=0 atom
} ADT Glist
10
基 结构的创建和销毁 InitGList(&L); DestroyGList(&L); 本 CreateGList(&L, S); CopyGList(&T, L); 操 作 状态函数
广义表的定义(精)

f(g)=
1 MAX{f(subg)}+1
int GLDepth(GLNode *g) /*求带头结点的广义表g的深度*/ { int max=0,dep; if (g->tag==0) return 0; /*为原子时返回0*/ g=g->val.sublist; /*g指向第一个元素*/ if (g==NULL) return 1; /*为空表时返回1*/ while (g!=NULL) /*遍历表中的每一个元素*/ { if (g->tag==1) /*元素为子表的情况*/ { dep=GLDepth(g); /*递归调用求出子表的深度 */ /*max为同一层所求过的子表中深度的最大值*/ if (dep>max) max=dep; } g=g->link; /*使g指向下一个元素*/ } return(max+1); /*返回表的深度*/ }
C a b c d
C a b c d
广义表的存储结构
广义表的情况 :
g2 1
∧
g1
1
∧
∧
*
*
*
*
…
*
*
∧
第 1 个元素 (a)空表
第 2 个元素 (b)非空表
第 n 个元素
为原子的情况 :
g3 0 a
∧
typedef struct lnode { int tag; union { ElemType data; /*结点类型标识*/
A()
A B e a b c d C A e
B(e)
D B a b c d C
C(a,(b,c,d))
数据结构广义表

结点结构是无论什么结点都有三个域:
第一个域是结点类型标志tag; 第二个域是指向一个列表的指针(当tag=1时) 或一个原子(当tag=0时); 第三个域是指向下一个结点的指针tp。
3 广义表的存储结构
形式描述为:
typedef enum{ ATOM, LIST }ElemTag typedef struct GLNode { //定义广义表结点 ElemTage tag; //公共部分,用以区分 原子结点和表结点 Unin{ //原子结点和表结点的联合部分 AtomType atom;//原子类型结点域, // AtomType由用户定义 struct GLNode *hp,; //表结点的表头指针域 }; struct GLNode *tp; //指向下一个结点的指针 }*Glist; //广义表类型
5. E=(a,E)
这是一个递归列表,其元素中有自己。
广义表也可以用图形表示,例如前述的广义表D和E可表示为:
广义表D
D
广义表E
E
C
A
B
a
e
a b c d
2 广义表的基本运算
广义表的基本运算 ⑴ 取表头 HEAD(LS); ⑵ 取表尾 TAIL(LS)。
3 广义表的存储结构
广义表中的数据元素可以是单元素,或是广义表, •很难用顺序存储结构表示,常采用链式存储结构。 1.表头表尾链存储结构 有两类结点:表结点和单元素结点。
P 1 3 1 1
A=y((c,3),(D,2)) C=x((1,10),(2,6))
^
1 2
A
z y 1 1 1 3
C
x 0 0 15 ^
B
1 2
1 2
^
数据结构第06章广义表

第6章广义表z6.1 广义表的基本概念z6.2 广义表的存储结构z6.3 广义表的操作算法16.1 广义表的基本概念广义表(列表)的概念-n( ≥0 )个表元素组成的有限序列,记作LS= ( a1, a1, a2, …, a n)LS是表名,a i是表元素,它可以是单个元素(称为原子) ,可以是表(称为子表) 。
n为表的长度。
n= 0 的广义表为空表。
n> 0时,表的第一个表元素称为广义表的表头(head),除此之外,其它表元素组成的表称为广义表的表尾(tail)。
2广义表举例:(1)A=()(2)B=(e)(3)C=(a, (b, c, d) )(4)D=(A,B,C)(5)E= (a , E)9任意一个非空广义表,均可分解为表头和表尾。
9对于一个非空广义表,其表头可能是原子,也可能是子表;而表尾一定是子表。
3广义表的基本操作:•结构的创建和销毁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());66. 2 广义表的存储结构z由于广义表中的元素不是同一类型,因此难以用顺序结构表示,通常采用链接存储方法存储广义表,并称之为广义链表。
z由于广义表中有两种数据元素,原子或子表,因此,需要两种结构的结点:一种是表结点,一种是原子结点。
z下面介绍一种广义表的链式存储结构。
78扩展的线性链表表示法:-子表结点由三个域组成:标志域、表头指针域和指向下一个元素的指针域;-原子结点的三个域为:标志域、值域和指向下一个元素的指针域。
数据结构广义表

22
创建广义表
创建广义表就是按照所给的表示具体广义表的字符串 str创建一个广义表h。
和头链和尾链存储结构广义表的创建算法类同,原子 和子表存储结构的创建广义表操作同样可以分解为创建 表头广义表和创建表尾广义表。
把表示广义表的字符串str分解成表头字符串hstr和表 尾字符串str的函数DecomposeStr(str, hstr)设计和前面的 方法完全相同。
{ for(j = 0; j < i-1; j++) hstr[j] = str[j+1];
hstr[j] = '\0';
if(str[i] == ',') i++;
str[0] = '(';
for(j = 1; i <= n-2; i++, j++) str[j] = str[i];
str[j] = ')';
这样,还需要设计一个把表示广义表的字符串str分解 成表头字符串hstr和表尾字符串str的函数 DecomposeStr(str, hstr)。
14
void DecomposeStr(char str[], char hstr[])
{ int i, j, tag, n = strlen(str);
pre = h; for(max = 0; pre != NULL; pre = pre->val.subList.tail) { dep = GListDepth(pre->val.subList.head);
if(dep > max) max = dep; } return max + 1; }
广义表的head和tail运算讲解

广义表的head和tail运算讲解一、引言广义表是一种常用的数据结构,它可以包含任意类型的元素,包括其他广义表。
广义表的h ea d运算和ta il运算是对广义表进行操作的两个基础运算,本文将对这两个运算进行详细讲解。
二、广义表的定义广义表是指可以包含各种元素的线性表,其中的元素可以是原子元素(如整数、字符等),也可以是广义表。
广义表由一系列元素组成,用括号表示,元素之间用逗号隔开。
三、h e a d运算h e ad运算用于获取广义表的第一个元素。
下面是h ea d运算的示意图:```广义表:(a,b,c,d,...)h e ad运算结果:a```四、t a i l运算t a il运算用于获取广义表除第一个元素外的剩余元素组成的广义表。
下面是t ai l运算的示意图:```广义表:(a,b,c,d,...)t a il运算结果:(b,c,d,...)```五、示例与应用假设有一个广义表`(1,(2,3),(4,(5,6)))`,我们可以通过h ea d运算和ta il运算来获取广义表中的元素。
-对该广义表进行hea d运算,将返回第一个元素1。
-对该广义表进行ta i l运算,将返回剩余元素组成的广义表`(2,3)`。
广义表的he ad和t ai l运算可以应用于各种场景。
例如,在处理嵌套列表时,可以通过递归地使用he ad和t ai l运算,来遍历并处理广义表中的所有元素。
以下是一个示例代码,演示了如何使用he a d和ta il运算来遍历广义表:```p yt ho n定义一个函数,用于遍历广义表d e ft ra ve rs e(ls t):i f ls t==[]:r e tu rnp r in t(ls t.he ad())t r av er se(l st.t ail())调用函数进行遍历l s t=Li st(1,L is t(2,Li st(3,L is t(4,L i st(5)))))t r av er se(l st)```通过以上示例,我们可以清晰地看到广义表的he ad和t ai l运算在遍历广义表时的作用。
第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); }
c语言 广义表

C语言广义表1. 什么是广义表?广义表(Generalized List),简称GList,是一种线性链表的扩展结构,也是一种特殊的树结构。
与传统的线性链表不同,广义表的节点可以存储原子数据和子表(也就是另一个广义表)。
在C语言中,可以使用指针和结构体来实现广义表。
每个节点包含两个指针域,分别指向下一个节点和子表。
通过这种方式,可以灵活地表示复杂的数据结构。
2. 广义表的表示方法广义表有两种常用的表示方法:括号表示法和逻辑列表法。
2.1 括号表示法括号表示法使用括号来标识子表,并用逗号分隔元素。
例如,(1, (2, 3), (4, (5, 6)))表示一个包含三个元素的广义表,其中第一个元素是原子数据1,第二个元素是一个包含两个原子数据2和3的子表,第三个元素是一个包含两个原子数据4和另一个包含两个原子数据5和6的子表。
2.2 逻辑列表法逻辑列表法使用空格或其他特殊符号来分隔元素,并用一对方括号将所有元素括起来。
例如,[1, [2 3], [4 [5 6]]]表示同样的广义表。
3. 广义表的操作广义表支持一系列的操作,包括创建、插入、删除、查找等。
3.1 创建广义表可以通过递归的方式创建广义表。
首先创建一个节点,然后判断当前元素是原子数据还是子表。
如果是原子数据,则将其存储在节点中;如果是子表,则递归创建子表并将其存储在节点中。
3.2 插入元素插入元素可以分为两种情况:在指定位置前插入一个新元素和在指定位置后插入一个新元素。
在指定位置前插入一个新元素时,需要先找到要插入位置的前一个节点,然后创建一个新节点,并将新节点的指针域指向要插入位置的节点,再将要插入位置的前一个节点的指针域指向新节点。
在指定位置后插入一个新元素时,需要先找到要插入位置的节点,然后创建一个新节点,并将新节点的指针域指向要插入位置的下一个节点,再将要插入位置的节点的指针域指向新节点。
3.3 删除元素删除元素也可以分为两种情况:删除指定位置上的元素和删除指定值的元素。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
课堂练习
一、单项选择
1、常对数组进行的两种基本操作是——
A、建立与删除
B、索引和修改
C、存取和修改
D、查找和索引
2、广义表((a),a)的表头是——,表尾是——
A、a
B、(a)
C、()
D、((a))
3、广义表((a))的表头是——
A、a
B、(a)
C、()
D、((a))
4、广义表((a,b),c,d)的表头是——,表尾是——
A、a
B、(a)
C、(a,b)
D、(c,d)
E、c,d
F、(d)
5、广义表(a,b,c,d)的表头是——,表尾是——
A、a
B、(a)
C、d
D、(d)
E、(b,c,d)
6、广义表((a,b,c,d))的表头是——,表尾是——
A、(a)
B、a
C、()
D、(a,b,c,d)
E、a,b,c,d
F、((a,b,c,d))
二、判断
1、广义表就是数据元素全是表的一种数据结构。
()
2、一个广义表的表头。
一个广义表。
()
3、一个广义表的表尾总是广义表。
()
三、填空
1、广义表((a),((b),c),(((d))))的表头是——,表尾是——,长度是——,
深度是——。
(深度是指广义表中所包含括号的层数)
2、广义表(a,(a,b),d,e,((I,j),k))的表头是——,表尾是——,长度
是——,深度是——。
3、设HEAD[p]为求广义表p的表头函数;TAIL[p]为求广义表p的表尾函数,其中[ ]
是函数的符号,请给出下列广义表的运算结果。
(1)、HEAD [(a,b,c)] 的结果是——
(2)、TAIL [(a,b,c)] 的结果是——
(3)、HEAD [((a),(b))] 的结果是——
(4)、TAIL [((a),(b))] 的结果是——
(5)、HEAD [ TAIL [(a,b,c)] ]的结果是——
(6)、TAIL [ HEAD [ ((a,b),(c,d))] ]的结果是——
(7)、HEAD [ HEAD[((a,b),(c,d))] ]的结果是——
(8)、TAIL [ TAIL [(a,(c,d))] ] 的结果是——
4、一个广义表中元素分为——元素和——元素两类。
5、一个广义表的深度等于——嵌套的最大层数。
6、在广义表的存储结构中,每个结点均包含有——个域。
7、在广义表的存储结构中,单元素结点与表元素结点有一个域对应不同,各自分别为
——域和——域。
四 分别使用表头表尾链存储结构、同层结点链存储结构画出下列广义表的存储结构图。
(1)( ( ( (a ),b ) ),( ( ( ),(d ) ),(e ,f ) ) ); (2)( ( (a ,b ,( )),( ),(a ,b ))),( ) )。
五、已知以下各图为广义表的存储结构图,写出各图表示的广义表。
(1)、 list
(2)
list。