广义表存储结构与算法设计分析

合集下载

个人对数据结构的理解和总结

个人对数据结构的理解和总结

个⼈对数据结构的理解和总结 在很多编程⼈员的潜意识⾥总是觉得数据结构知识似乎没什么⽤,因为⼯作中似乎从来都没有涉及到数据结构的什么内容。

我对这样的认识只能报以呵呵~ 也难怪,其实有这些想法的同⾏在⼯作中的⼤部分都是如此⾛过来的:掌握⼏种常⽤Web框架,⽐如SSH,然后不停的堆砌已有的API做⼀些对数据库的增删改查之类的简单代码设计,最后反正功能是实现了,是否设计⽆误,效率⼜优,就⼏乎没有⼈去管了。

也是,这样的⼯作也基本涉及不到有⽤到数据结构知识去解决问题的地⽅。

其实,有这样想法⼈算不上真正的软件开发者,或者层次还不深,因为数据结构是软件开发中最基础最重要的理论基础。

1. 为什么数据结构很重要⾸先为什么要开发各种各样的软件,⽬的只有⼀个:就是利⽤计算机来为⼈们处理各种数据并以⼀定的形式展现出来供⽤户使⽤。

随着计算机的应⽤范围的不断扩⼤,计算机所需要处理的数据越来越复杂,并且规模越来越⼤,计算机所处理的数据已不再是单纯的数值数据,⽽更多的是⾮数值数据。

另⼀⽅⾯,现实中需要处理的数据并不是杂乱⽆章的,它们⼀定有内在的各种联系,但这需要算法设计⼈员去总结、归纳、建模、然后抽象出⼀个具体的模型来表⽰—,我们将这个模型成为数据的逻辑结构。

然后聪明的设计师再围绕这个创建的逻辑结构总结设计出⼀套处理⽅法,这样,数据有了,模型有了,算法有了,在理论上问题就可以解决了。

剩下的就应该交给计算机去做了,但以上都是基于逻辑上的设计,计算机才不懂这些。

所以接下来还需要对应的存储结构来将要处理的数据先存储到计算机中,再将那些处理逻辑(算法)⽤相应的代码实现,计算机才能对数据进⾏有效的处理。

2. 什么是数据结构数据结构:即⼈们抽象出来的描述现实世界实体的数学模型(⾮数值计算)及其上的操作(运算),在计算机上的表⽰和实现。

数据结构就是指按⼀定的逻辑结构组成的⼀批数据,使⽤某种存储结构将这批数据存储于计算机中,并在这些数据上定义了⼀个运算集合。

广义表的存储结构

广义表的存储结构

广义表的存储结构广义表是一种表示数据结构的层次形式。

广义表的数据结构具有弹性,可以用来表示任意复杂度的对象,广泛应用于计算机科学中,在许多普通的程序设计语言中,这是一种重要的数据类型。

简而言之,它可以表示更复杂的结构,例如树形结构和图形结构。

广义表是一种递归结构,它由多个元素构成。

一个广义表的元素可以是一个基本的值,也可以是一个广义表,表示下一级的数据结构。

基本元素可以是任何数据类型,而广义表的元素可以是任意复杂度的数据结构。

因此,广义表用来表示任意复杂度的数据结构有着十分强大的表示能力,成为一种强大的数据结构表示方式。

当处理广义表的存储问题时,需要考虑到其数据的特点,只有当特点被有效考虑到时,储存和操作广义表才能更有效地实现。

为了实现更有效的存储,一般有三种方式可以考虑:链式储存、双亲表示法和结点表示法。

链式储存是一种比较简单的方式,把广义表的每个元素都以链表的形式存储下来,这种方式可以方便地查找元素,操作形式也比较简单,但是因为引入了指针,而且每个结点只有一个指针,所以存储空间利用率低,不够高效。

双亲表示法是利用普通表表示广义表的一种方式,它把广义表的每个元素都储存在一个有限的表格中,每个元素的表格包括元素的值、子节点的位置、双亲节点的位置等,以此来表示广义表的结构关系。

双亲表示法的优点是其存储效率高,把每个元素的值和其结构关系存储在一张表中,存储空间利用率比较高,但是它的查找和操作效率比较低,需要大量的遍历操作。

结点表示法是另一种表示广义表的方式,它把广义表的每个元素都储存在一个节点中,每一个节点中包含元素的值,以及指向该元素的子节点和双亲节点的指针,因此可以表示出广义表的层次结构。

结点表示法既可以查找结点和操作结点,又能存储元素的值和结构关系,所以其存储空间利用率较高,查找和操作也比较快,比较灵活。

总之,当处理广义表的存储问题时,可以通过链式储存、双亲表示法和结点表示法来实现更有效的存储,其中结点表示法比较灵活,在存储空间利用率上要优于其他方法。

第5章 广义表

第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); 操 作 状态函数

广义表存储结构与算法设计分析

广义表存储结构与算法设计分析
第2 9卷
第 2期

延安大学学报 ( 自然科学 版)
Ju l fYa a ies y( trlS in eE io o ma n nUnv ri Nau a ce c dt n o t i
Vol2 No 2 _9 .
21 0 0年 6月
Jn 2 l u .00
广 义 表 存 储 结 构 与 算 法 设计 分 析
1 广义表 的定 义
广 义表是 线性 表 的推 广 , 称列 表 , 泛应 用 于 也 广
为某个 数 据对象 } 和数 据 关 系 R(={ , ) <e e>I
e , ∈D, ≤i } ’ 同 时定 义 了若 干 广义 表 e 2 ≤凡 ) ,
人工智能等领域的表处理 LS 语言中 IP 引。广义表
层 次性是 广 义表 的主要 特 点之 一 。单 元 素结点
收 稿 日期 :0 0—0 1 21 3— 2 基 金 项 目 : 南 师 范 学 院 研 究 生 专 项 基 金 (0 K 0 7 渭 1Y Z 5 )
以是 单 个元 素 , 可 以是广 义表 。 也 卜
作者简介 : 王
敏 (9 2 ) 女 , 17 一 , 陕西临潼人 , 渭南师范学院讲师 。
构 , 出具体 的操 作 算 法 及 其 C语 言描 述 , 对 各 给 并
个算 法 进行 时 间复杂度 分 析 。

记 A T 描 述 中包括 广义 表 的数 据 对 象 D(={ i D) eI
12 … , ; , , n 凡≥0 e ∈ tm e 或 e ∈Gi ,tm e ; Ao St ltAo St s
的长 度 、 深度 、 头 及 表 尾 等 操 作 应 基 于 的 存 储 结 表

数据结构与算法问题分析及源代码之广义表

数据结构与算法问题分析及源代码之广义表

广义表1 题目编写一个程序,实现广义表的各种运算,并在此基础上设计一个程序完成如下功能:建立广义表g=“(b,(b,a),((a,b),c))”的链式存储结构。

输出广义表g的长度。

输出广义表g的深度。

2 目标熟悉广义表的定义及其基本操作的实现3 设计思想链式存储的广义表,结点包含数据区,指针,以及一个标记头结点的整型数。

广义表的表示结构为:(a,b),其中a、b可以是字符或广义表。

因此,可以用递归算法来实现对它的定义与操作。

4 算法描述(1)创建广义表:逐个输入表示广义表的字符串,以‘(’为起始标志建立结点并标记为头结点,递归调用此操作建立广义表;若读入‘)’则将最后结点的指针置空;读入非结束字符,赋值到结点数据区,并赋值指针形链式结构,两个结点之间打印‘,’。

(2)求广义表长度:广义表基本组成元素(a,b)若a、b不是广义表则(a,b)深度为一。

广义表的深度等于表头结点的数量,从表头结点遍历广义表,对每一个广义表结点应用该函数,若tag==1(结点是表头)则返回计数器加一,否则返回0。

(3)输出广义表:从表头开始,测试结点指针,若指针指向结点的标记位为1,则先打印‘(’再输出其数据值,并调用该操作输出下一个结点;函数返回时,测试指针指向结点的标记位,若为1,则先打印‘)’,再调用该函数输出下一个结点数据;每次输出数据值以后测试该结点是否为子广义表的最后一个结点,不是则输出‘,’,否则返回。

5 程序结构图6 源程序#include<iostream.h>#include<malloc.h>#include <stdio.h>typedef struct lnode{int tag;union{char atom;struct lnode *p;}ptr;struct lnode *q;}Lnode;Lnode *CreatGL(){ // 创建一个广义表,表中元素为字符Lnode *h;char ch;ch=getchar();if(ch){h=(Lnode*)malloc(sizeof(Lnode)); //为表分配内存空间if(ch=='('){h->tag=1;h->ptr.p=CreatGL(); //用递归的方法实现创建广义表的操作}else if(ch==')')h=NULL;else{h->tag=0;h->ptr.atom=ch;}}else h=NULL;ch=getchar();if(h!=NULL)if(ch==',')h->q=CreatGL();elseh->q=NULL;return h;}int GLLength(Lnode *g){ // 求广义表的长度int n=0;g=g->ptr.p;while(g){n++;g=g->q;}return n;}int GLDepth(Lnode *g){ // 求广义表的深度int max=0,dep;if(g->tag==0)return 0;g=g->ptr.p;if(g==NULL)return 1;while(g){if(g->tag==1){dep=GLDepth(g);if(dep>max)max=dep;}g=g->q;}return (max+1);}void DispGL(Lnode *g){ // 输出广义表if(g){if(g->tag==1){cout<<"(";if(g->ptr.p==NULL)cout<<" ";elseDispGL(g->ptr.p);}elsecout<<g->ptr.atom;if(g->tag==1)cout<<")";if(g->q){cout<<",";DispGL(g->q);}}else cout<<"广义表不存在"<<endl; }#include <stdio.h>#include <stdlib.h>#include<iostream.h>#include"glist.h"int main(){char choice;Lnode *glist;cout<<"键入广义表:"<<endl;glist=CreatGL();system("cls");printf("请选择(输入0退出)\n1 输出广义表内容\n2 输出广义表长度\n3 输出广义表深度\n");cout<<endl<<"选择:";cin>>choice;while(choice!='0'){system("cls");printf("请选择(输入0退出)\n1 输出广义表内容\n2 输出广义表长度\n3 输出广义表深度\n");switch (choice){case '1':DispGL(glist);cout<<endl;break;case '2':cout<<"广义表的长度为: "<<GLLength(glist) <<endl;break;case '3':cout<<"广义表深度为:"<<GLDepth(glist)<<endl;break;case '0':return 0;}cout<<endl<<"选择:";cin>>choice;}。

数据结构与算法课程总结

数据结构与算法课程总结
第七章 图 教学要求: 本章目的是介绍图的基本概念、两种常用的存储结构、两种遍历算法以及图的应用算 法,要求在熟悉这些内容的基础上,重点掌握图的两种存储结构上实现的遍历算法。本章难 点是图的应用算法:求最小生成树,求单源最短路径以及拓扑分类,要求掌握这些算法的基 本思想及时间性能。 教学内容: 1.图的概念(领会) 1.1 图的逻辑结构特征。 1.2 图的常用术语及含义。 2.图的存储结构(简单应用) 2.1 邻接矩阵和邻接表这两种存储结构的特点及适用范围。 2.2 根据应用问题的特点和要求选择合适的存储结构。 3.图的遍历(简单应用) 3.1 连通图及非连通图的深度优先搜索和广度优先搜索两种遍历算法,其执行过程 以及时间复杂性分析。 3.2 确定两种遍历所得到的顶点访问序列。 3.3 图的两种遍历与树的遍历之间的关系。. 3.4 两种遍历所使用的辅助数据结构(钱或队列)在遍历过程中所起的作用。 3.5 利用图的两种遍历设计算法解决简单的应用问题。 4.生成树和最小生成树(领会)
本课程的先修可称为离散数学和高级语言程序设计,后续课程为操作系统、数据库系统 原理和编译原理等。
数据结构中的存储结构及基本运算的实现需要程序设计的基本知识和编程能力和经验, 本课程大部分实例和实验均是用 C 语言实现的,故要求叫熟练地掌握 C 语言。 三、选用的教材及参考书
教材选用《数据结构与算法》,大连理工大学出版社,作者郭福顺、廖明宏等。参考书 为《数据结构(C 语言版》,清华大学出版社出版,严蔚敏、吴伟民编著。 四、教学内容
第六章 树 教学要求: 本章目的是二元树的定义、性质、存储结构、遍历、线索化,树的定义、存储结构、 遍历、树和森林与二元树的转换,哈夫曼树及其应用(优化判定过程和哈夫曼编码)等内容。 要求在熟悉这些内容的基础上,重点掌握二元树的遍历算法及其有关应用,难点是使用本章 所学到的有关知识设计出有效算法,解决与树或二元树相关的应用问题。 教学内容 1.树的概念(领会) 1.1 树的逻辑结构特征。 1.2 树的不同表示方法。 1.3 树的常用术语及含义。

《数据结构与算法》第五章-数组和广义表学习指导材料

《数据结构与算法》第五章-数组和广义表学习指导材料

《数据结构与算法》第五章数组和广义表本章介绍的数组与广义表可视为线性表的推广,其特点是数据元素仍然是一个表。

本章讨论多维数组的逻辑结构和存储结构、特殊矩阵、矩阵的压缩存储、广义表的逻辑结构和存储结构等。

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)所示。

广义表的应用课程设计

广义表的应用课程设计

广义表的应用课程设计一、课程目标知识目标:1. 理解广义表的定义和基本概念;2. 学会使用广义表表示复杂的线性结构;3. 掌握广义表的基本操作,如创建、插入、删除、查找等;4. 能够运用广义表解决实际问题。

技能目标:1. 能够运用广义表的基本操作,实现线性结构的存储和运算;2. 能够分析实际问题,选择合适的广义表结构进行建模;3. 能够编写简单的程序,利用广义表解决具体问题;4. 培养学生的逻辑思维能力和编程实践能力。

情感态度价值观目标:1. 培养学生对数据结构和算法的兴趣,激发学习热情;2. 培养学生的团队协作意识和解决问题的能力;3. 培养学生面对复杂问题,勇于尝试、积极探究的精神;4. 增强学生的自信心和成就感,鼓励他们发挥创新精神。

课程性质:本课程为计算机科学领域的数据结构与算法课程,旨在帮助学生掌握广义表这一数据结构,并运用其解决实际问题。

学生特点:学生具备一定的编程基础,对数据结构有一定了解,但可能对广义表的认识较为陌生。

教学要求:结合学生特点,注重理论与实践相结合,通过实例讲解、课堂互动、上机实践等环节,使学生掌握广义表的应用。

同时,关注学生的情感态度,激发学习兴趣,培养其解决问题的能力和团队协作精神。

在教学过程中,将课程目标分解为具体的学习成果,以便于教学设计和评估。

二、教学内容1. 广义表的定义与基本概念:- 线性表、广义表的概念与区别;- 广义表的元素、表头、表尾及表长等基本概念。

2. 广义表的存储结构:- 顺序存储结构;- 链式存储结构。

3. 广义表的基本操作:- 创建广义表;- 插入、删除、查找等操作;- 广义表的遍历。

4. 广义表的应用:- 利用广义表解决实际问题,如多项式的表示与运算;- 广义表在数据压缩中的应用;- 广义表在计算机图形学中的应用。

5. 教学案例与上机实践:- 结合实际案例,分析广义表的应用场景;- 上机实践,编写程序实现广义表的基本操作;- 团队协作,共同探讨广义表在解决复杂问题中的应用。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

广义表存储结构与算法设计分析(论文)薛金凤(内蒙古师范大学青年政治学院)摘要:给出了存储广义表两种不同存储结构的具体类型定义及其C 语言描述,对两种不同存储结构下广义表的几种基本操作算法——求广义表的长度、深度、表长和表尾等算法进行了分析设计,并给出相应算法的C 语言描述和时间复杂度分析,为数据结构相关章节的教学起到一定的指导作用。

关键词:广义表;抽象数据类型;C 语言;时间复杂度广义表在《数据结构》课程的实际讲授中,一般作为由线性结构向非线性结构进行过渡的部分,大多数参考文献对于该部分内容都只给出简单的介绍,而并未给出具体的算法实现;但仔细分析广义表的逻辑结构特点,发现数据结构中的绝大多数逻辑结构都可以归纳为广义表结构,广义表在数据结构中应该占据相当重要的位置,如果让广义表统领大多数的数据存储结构,有利于增强学生的总结概括能力,对《数据结构》课程相关章节的教学也起到推波助澜的作用。

本文将介绍广义表所采用的两种不同存储结构,及其C 语言描述的类型定义,分析求解广义表的长度、深度、表头及表尾等操作应基于的存储结构,给出具体的操作算法及其C 语言描述,并对各个算法进行时间复杂度分析。

1 广义表的定义广义表是线性表的推广,也称列表,广泛应用于人工智能等领域的表处理LISP 语言中。

广义表一般记作LS=(12,.......n a a a ),其中n 为表长,i a 可以是单个元素,也可以是广义表。

层次性事广义表的主要特点之一。

单元素结点(原子结点)没有子结点;表结点或者问空表结点,或者拥有子结点;表结点和它的子结点分布在广义表的不同层次上。

广义表划分结点层次的规则:头结点定义为第一层结点;属于第k 层次子表结点的结点定义为第k+1层次结点,k=1,2,…定义1 广义表第一层次中元素结点的个数称为广义表的长度。

11收稿日期:2012年6月12作者简介:薛金凤,内蒙古包头人,即将毕业于内蒙古师范大学青年政治学院。

定义2 广义表中结点的最大层次称为广义表的深度。

定义3 在广义表LS=(12,.......n a a a )中,首元素1a 称为广义表的表头,而其余元素构成的表(12,.......n a a a )称为广义表的表尾。

广义表的抽象数据类型(Abstract Data Type 简记ADT )描述中包括广义表的数据对象D ({}1,2,...,;0;e ,i i i e i n n e AtomSet Glist AtomSet ==≥∈∈或为某个数据对象)和数据关系R({}11e ,,,2i i i i e e e D i n --<>∈≤≤)同时定义了若干广义表的基本操作,包括:广义表的初始化、建立、销毁、复制、判空、求广义表长度、求广义表深度、求广义表表头、求广义表表尾、向广义表表头插入元素、删除广义表表头元素以及遍历广义表等操作。

2 广义表的存储表示为实现广义表的基本操作,首先需要考虑其存储结构。

由于广义表中的元素即可能是单元素又可能是子表,难以用顺序结构来表示,因而通常采用链式存储结构进行存储。

可以采用两种不同的存储方案:一是原子结点与表结点同构;二是原子结点与表结点异构。

2.1 原子结点与表结点同构的存储表示 原子结点与表结点同构,指的是无论原子结点还是表结点均由3个域构成(又称广义表的孩子兄弟表示法)。

设定tag 域为0表示该结点为原子结点,此时另外两个域分别存储结点的元素值和指向其后继结点起始地址的指针;tag 域为1表示该结点为表结点,此时另外两个域分别为指向表头的指针和指向后继结点起始地址的指针。

采用同构存储结构时,广义表的定义类型可用C 语言描述如下:Typedef enum {ATOM,LIST}Elem Tag;Typedef struct GLNode{Elem Tagtag ;//区别两种结点的标志域Union{Atom Typeatom;//原子结点值域Struct GLNode *hp;//指向表头的指针}Struct GLNode *tp;//指向后继结点的指针}* Glist_1;2.2原子结点与表结点异构的存储表示原子结点与表结点异构,指的是原子结点仅由tag和atom2个域组成,而表结点则由tag、hp和tp3个域构成(又称广义表的头尾表示法)同样设定tag域为0时表示该结点为原子结点,此时atom域用于存储结点的元素值;tag域为1表示该结点为表结点,此时另外两个域分别为指向表头和指向表尾的指针。

采用异构存储结构时,广义表的定义类型可用C语言描述如下:Typedef enum{ATOM,LIST}ElemTag;Typedef struct GLNode {Elem Tagtag;//区别两种结点的标志域Union{AtomType atom ;//原子结点值域Struct{struct GLNode *hp;//指向表头的指针Struct GLNode *tp;//指向表尾的指针}ptr;}* Glist_2;3广义表相关操作的算法分析与设计广义表抽象数据类型描述的基本操作中,初始化、建立、销毁、复制以及判空等前5个操作为最简操作,其算法对于采用哪种存储结构没有特殊要求;后面7种操作则针对不同的存储结构,其算法设计方法均有一定的不同。

下面着重给出求广义表长度、深度、表头和表尾等操作的算法设计分析。

3.1求广义表长度的算法求广义表的长度即统计广义表第一层次中元素结点的个数。

该操作的初始条件为广义表已存在,操作结果即返回求得的广义表长度(元素个数)。

由原子结点与表结点同构的存储结构可以看出:无论原子结点还是表结点的tp域,均为指向该结点后继结点起始地址的指针,因此,可通过在该存储上,从广义表的hp指针链接的结点个数,从而求得广义表的长度。

其操作算法可用C语言描述如下(设广义表L已建立,其类型为Glist_1);Int Glist Lengh(Glist_1 L){int count=1;Glist_1 p=L→hp;While (p→tp)//p所指结点后继非空{p=p→tp;count + +;}//指针后移并计数retuncount;}3.2求广义表深度的算法广义表的深度指的是广义表中结点的最大层次,等于所有子表中表的最大深度加1,若一个广义表为空或仅由原子结点组成,则深度为1.该操作的初始条件为广义表已存在,操作结果返回求得的广义表的深度。

可以通过计数指针在不同层次结点中的移动情况计算出广义表的深度。

该操作可采用两种存储结构中的任意一种。

设采用同构的存储结构Glist_1,则求广义表深度的递归算法可用C语言描述如下(设广义表L已建立):Int GlistDepth(Glist_1L){intcount,depth;For(depth=0;L→hp;L= L→hp →tp)//L非空If(L→hp →tag)//L的表头为子表结点{count =GlistDepth(L→hp);If(count>depth)depth=count;}Returndepth+1;}3.3求广义表表头的算法广义表表头即广义表中的首元素,求表头操作的初始条件为广义表已存在,操作结果返回广义表的表头结点。

由两种存储结构均可以肯出:结点的hp域为指向该结点的表头结点起始地址的指针,因此,采用两种存储结构中的任何一种均可通过广义表表头结点的hp指针求得广义表的表头(异构存储结构时当广义表非空)。

设广义表L已基于结点同构的存储结构Glist_1创建并生成,其操作算法可用C语言描述如下:Glist_1 GetHead(Glist_1L){return(L→hp);}若广义表L已基于结点异构的存储结构Glist_2创建并生成,则其操作算法可用C语言描述如下:Glist_2 GetHead(Glist_2L){if(L= = NULL)Ruturn(NULL);//采用异构存储结构时广义表头指针为空则返回空指针ElseReturn(L→ptr.hp);}3.4求广义表表尾的算法广义表表尾是由广义表中自第二个元素之后的其余元素构成的子表,求表尾操作的初始条件为广义表已存在,操作结果求得广义表的表尾。

由原子结点与表结点异构的存储结构可以看出:广义表非空时,其表头结点的tp域即为指向广义表表尾子表的指针,因此,可通过广义表表头结点的tp域求得广义表的表尾。

其操作算法可用C语言描述如下(设广义表L已建立,其类型为Glist_2):Glist_2 Get Tail(Glist_2L){if(L= = NULL)Return(NULL);//采用异构存储结构时广义表头指针为空则返回空指针ElseReturn( L→ptr.tp);}3.5算法时间复杂度分析求广义表长度的算法函数Glist Lengh 中包含一个while循环,循环体基本语句p=p→tp;和count + +;的执行次数取决于广义表中结点的个数n(看作问题的规模),当广义表深度为1时,n即为广义表的长度,从而循环体基本语句的执行次数最大为n 次,因而算法的时间发杂度为线性阶,即T(n)=O(n)。

求广义表深度的算法函数GlistDepth 中包含一个for循环,算法的基本操作为循环体中的语句,循环体的执行次数跟广义表的结点数n(视作问题的规模)成正比,GlistDepth(p→hp)递归调用的次数则跟广义表的深度depth成正比,因此,算法的时间复杂度为T(n)=O(n+m)。

求广义表表头的两个不同存储结构上的算法函数GetHead中,均只包含一条基本语句,因而算法的时间复杂度为常数阶,即T(n)=O(1)。

3.6结论前述各基本算法的C语言描述均已通过完整的上机测试。

由原子结点与表结点同构的孩子兄弟表示法可以看出:存储结构Glist_1中,无论原子结点还是表结点的tp域均为指向该结点后继结点起始地址的指针,因此,该存储结构较适用于求解区分广义表表头和表尾等的相关操作。

参考文献:[1]张复兴、孙甲霞.广义表在数据结构中的位置[J].河南科技学院学报(自然科学版).2006,34(4):103-104.[2]严蔚敏,吴伟民.数据结构[M].北京:清华大学出版社,2006,109-112.。

相关文档
最新文档