计算机一级编号什么数带头,2017年全国计算机等级考试四级复习纲要:树型结构...

本文探讨了树结构的基础概念,包括树的基本运算,如求根、双亲和孩子,以及二叉树的特性和存储结构。重点介绍了二叉树的遍历方法(先根、中根、后根),树与二叉树、森林的转换技巧。适合理解和应用树型数据结构的开发者。
摘要由CSDN通过智能技术生成

00837299fca5f17d14d316abbff0f0ff.png

四、树型结构

线性表、栈和队列等数据结构所表达和处理的数据以线性结构为组织形式。然而,在计算机科学和计算机应用的各个领域中,存在着大量需要用更复杂的逻辑结构加以表示的问题。因此必须研究更复杂的逻辑结构及相应的数据结构。树形结构就是这些更复杂的结构中最重要的一类。

1.树的基本概念

树是一类重要的树形结构,其定义如下:树是n(n>0)个结点的有穷集合,满足:

(1)有且仅有一个称为根的结点;

(2)其余结点分为m(m≥0)个互不相交的非空集合,T 1 ,T 2 ,…,T m ,这些集合中的每一个都是一棵树,称为根的子树。

在树上,根结点没有直接前趋。对树上任一结点X来说,X是它的任一子树的根结点惟一的直接前趋。为了讨论方便,我们引入树的若干习惯术语。树上任一结点所拥有的子树的数目称为该结点的度。度为0的结点称为叶子或终端结点。度大于0的结点称为非终端结点或分支点。一棵树中所有结点的度的值称为该树的度。若树中结点A是结点B的直接前趋,则称A为B的双亲或父结点,称B为A的孩子(即“子女”)或子结点。易知任何结点A的孩子B也就是A的一棵子树的根结点,父结点相同的结点互称为兄弟。一棵树上的任何结点(不包括根本身)称为根的子孙。反之若B是A的子孙,则称A是B的祖先,结点的层数(或深度)从根开始算起:根的层数为1,其余结点的层数为其双亲的层数加1。一棵树中所有结点层数的值称为该树的高度或深度。

树(及一切树形结构)是一种“分支层次”结构。所谓“分支”是指树中任一结点的子孙可以按它们所在的子树的不同而划分成不同的“分支”;所谓“层次”是指树上所有结点可以按它们的层数划分不同的“层次”。在实际应用中,树中的一个结点可用来存储实际问题中的一个数据元素,而结点间的逻辑关系(即父结点与子结点之间的邻接关系)往往用来表示数据元素之间的某种重要的、必须加以表达的关系。

用图示法表示任何树形结构时,箭头的方向总是从上到下,即从父结点指向子结点,因此,可以简单地用连线代替箭头。

2.树的基本运算包括:

①求根ROOT(T),引用型运算,其结果是结点X在树T的根结点。

②求双亲PARENT(T,X),引用型运算,其结果是结点X在树T上的双亲结点;若X是树T的根或X不在T上,则结果为一特殊标志。

③求孩子CHILD(T,X,i),引用型运算,其结果是树T上的结点X的第i个孩子;若X不在T上或X没有第i个孩子,则结果为一特殊标志。

④建树CREATE(X,T 1 ,…,T k )k≥1,加工型运算,其作用是建立一棵以X为根,以T 1 ,…,T k 为第1,…k棵子树的树。

⑤剪枝DELETE(T,X,i),加工型运算,其作用是删除树T上结点X的第i棵子树;若T无第i棵子树,则为空操作。

3.二叉树

(1)二叉树的基本概念

二叉树是结点的有穷集合,它或者是空集,或者同时满足下述两个条件:(1)有且仅有一个称为根的结点:

(2)其余结点分为两个互不相交的集合T 1 、T 2 ,T 1 与T 2 都是二叉树,并且T 1 与T 2 有顺序关系(T 1 在T 2 之前),它们分别称为根的左子树和右子树。

二叉树是一类与树不同的树形结构。它们的区别是:第一,二叉树可以是空集,这种二叉树称为空二叉树。第二,二叉树的任一结点都有两棵子树(当然,它们中的任何一个可以是空子树),并且这两棵子树之间有次序关系,也就是说,它们的位置不能交换。相应地,二叉树上任一结点左、右子树的根分别称为该结点的左孩子和右孩子。另外,二叉树上任一结点的度定义为该结点的孩子数(即非空子树数)。除这个几个术语之外,树的其它术语也适用于二叉树。

特别值得注意的是,由于二叉树上任一结点的子树有左、右之分,因此即使一结点只有一棵非空子树,仍须区别它是该结点的左子树还是右子树,这是与树不同的。

(2)二叉树的性质

在某些情况下,了解二叉树的下列性质是有帮助的。

4.二叉树的存储结构

二叉树通常有两类存储结构,顺序存储结构和链式存储结构。

(1)二叉树的链式存储结构

二叉树有不同的链式存储结构,其中最常用的是二叉树链表与三叉链表。

其中,data域称为数据域,用于存储二叉树结点中的数据元素;lchild域称为左孩子指针域,用于存放指向本结点左孩子的指针(这个指针及指针域有时简称为左指针)。类似地,rchild域称为右孩子指针域,用于存放指向本结点右孩子的指针(简称右指针)。二叉链表中的所有存储结点**它们的左、右指针的链接而形成一个整体。此外,每个二叉链表还必须有一个指向根结点的指针,该指针称为根指针。根指针具有标识二叉链表的作用,对二叉链表的访问只能从根指针开始。值得注意的是,二叉链表中每个存储结点的每个指针域必须有一个值,这个值或者是指向该结点的一个孩子的指针,或者是空指针NULL。

若二叉树为空,则root=NULL。若某结点的某个孩子不存在,则相应的指针为空。具有n个结点的二叉树中,一共有2n个指针域,其中只有n-1个用来指向结点的左右孩子,其余的n+1个指针域为NULL。

二叉树的链式存储结构操作方便,表达简明(二叉树的逻辑关系———结点间的父子关系———在二叉链表和三叉链表中被直接表达成对应存储结点之间的指针),因而成为二叉树最常用的存储结构。然而在某些情况下,二叉树的顺序存储结构也很有用。

(2)二叉树的顺序存储结构

二叉树的顺序存储结构由一个一维数组构成,二叉树上的结点按某种次序分别存入该数组的各个单元。显然,这里的关键在于结点的存储次序,这种次序应能反映结点之间的逻辑关系(父子关系),否则二叉树的基本运算就难以实现。

由二叉树的性质5可知,若对任一完全二叉树上的所有结点按层编号,则结点编号之间的数值关系可以准确地反映结点之间的逻辑关系。因此,对于任何完全二叉树来说,可以采用“以编号为地址”的策略将结点存入作为顺序存储结构的一维数组。具体地说就是:将编号为i的结点存入一维数组的第i个单元。

在这一存储结构中,由于一结点的存储位置(即下标)也就是它的编号,故结点间的逻辑关系可**它们下标间的数值关系确定。来源:www.examda.com

5.二叉树的遍历

由于二叉树的基本运算在链式存储结构上的实现比较简单,无需详加讨论。下面研究二叉树的一种较为复杂的重要运算———遍历及其在二叉链表上的实现。

遍历一棵二叉树就是按某种次序系统地“访问”二叉树上的所有结点,使每个结点恰好被“访问”一次。所谓“访问”一个结点,是指对该结点的数据域进行某种处理,处理的内容依具体问题而定,通常比较简单。遍历运算的关键在于访问结点的“次序”,这种次序应**二叉树上的每个结点均被访问一次且仅一次。

由定义可知,一棵二叉树由三部分组成:根、左子树和右子树。因此对二叉树的遍历也可相应地分解成三项“子任务”:

①访问根根点;

②遍历左子树(即依次访问左子树上的全部结点);③遍历右子树(即依次访问右子树上的全部结点)。

因为左、右子树都是二叉树(可以是空二叉树),对它们的遍历可以按上述方法继续分解,直到每棵子树均为空二叉树为止。由此可见,上述三项子任务之间的次序决定了遍历的次序。若以D、L、R分别表示这三项子任务,则人有六种可能的次序:DLR、LDR、LRD、DRL、RDL和RLD。通常限定“先左后右”,即子任务②在子任务③之前完成,这样就只剩下前三种次序,按这三种次序进行的遍历分别称为先根遍历(或前序遍历)、中根(或中序)遍历、后根(或后序)遍历。三种遍历方法的定义如下:

先根遍历 若需遍历的二叉树为空,执行空操作;否则,依次执行下列操作:

①访问根结点;

②先根遍历左子树;

③先根遍历右子树。

中根遍历 若需遍历的二叉树为空,执行空操作,否则,依次执行下列操作:

①中根遍历左子树;②访问根结点;③中根遍右子树。

后根遍历 若需遍历的二叉树为空,执行空操作,否则,依次执行下列操作:

①后根遍历左子树。②后根遍历右子树。③访问根结点。

显然,上述三种遍历方法的区别在于执行子任务“访问根结点”的“时机”不同;最先(最后、在中间)执行此子任务,则为先根(后根、中根)遍历。

按某种遍历方法遍历一棵二叉树,将得到该二叉树上所有结点的访问序列。

其中,data域称为数据域,用于存储二叉树结点中的数据元素;lchild域称为左孩子指针域,用于存放指向本结点左孩子的指针(这个指针及指针域有时简称为左指针)。类似地,rchild域称为右孩子指针域,用于存放指向本结点右孩子的指针(简称右指针)。二叉链表中的所有存储结点**它们的左、右指针的链接而形成一个整体。此外,每个二叉链表还必须有一个指向根结点的指针,该指针称为根指针。根指针具有标识二叉链表的作用,对二叉链表的访问只能从根指针开始。值得注意的是,二叉链表中每个存储结点的每个指针域必须有一个值,这个值或者是指向该结点的一个孩子的指针,或者是空指针NULL。

若二叉树为空,则root=NULL。若某结点的某个孩子不存在,则相应的指针为空。具有n个结点的二叉树中,一共有2n个指针域,其中只有n-1个用来指向结点的左右孩子,其余的n+1个指针域为NULL。

二叉树的链式存储结构操作方便,表达简明(二叉树的逻辑关系———结点间的父子关系———在二叉链表和三叉链表中被直接表达成对应存储结点之间的指针),因而成为二叉树最常用的存储结构。然而在某些情况下,二叉树的顺序存储结构也很有用。

(2)二叉树的顺序存储结构

二叉树的顺序存储结构由一个一维数组构成,二叉树上的结点按某种次序分别存入该数组的各个单元。显然,这里的关键在于结点的存储次序,这种次序应能反映结点之间的逻辑关系(父子关系),否则二叉树的基本运算就难以实现。

由二叉树的性质5可知,若对任一完全二叉树上的所有结点按层编号,则结点编号之间的数值关系可以准确地反映结点之间的逻辑关系。因此,对于任何完全二叉树来说,可以采用“以编号为地址”的策略将结点存入作为顺序存储结构的一维数组。具体地说就是:将编号为i的结点存入一维数组的第i个单元。

在这一存储结构中,由于一结点的存储位置(即下标)也就是它的编号,故结点间的逻辑关系可**它们下标间的数值关系确定。来源:www.examda.com

5.二叉树的遍历

由于二叉树的基本运算在链式存储结构上的实现比较简单,无需详加讨论。下面研究二叉树的一种较为复杂的重要运算———遍历及其在二叉链表上的实现。

遍历一棵二叉树就是按某种次序系统地“访问”二叉树上的所有结点,使每个结点恰好被“访问”一次。所谓“访问”一个结点,是指对该结点的数据域进行某种处理,处理的内容依具体问题而定,通常比较简单。遍历运算的关键在于访问结点的“次序”,这种次序应**二叉树上的每个结点均被访问一次且仅一次。

由定义可知,一棵二叉树由三部分组成:根、左子树和右子树。因此对二叉树的遍历也可相应地分解成三项“子任务”:

①访问根根点;

②遍历左子树(即依次访问左子树上的全部结点);③遍历右子树(即依次访问右子树上的全部结点)。

因为左、右子树都是二叉树(可以是空二叉树),对它们的遍历可以按上述方法继续分解,直到每棵子树均为空二叉树为止。由此可见,上述三项子任务之间的次序决定了遍历的次序。若以D、L、R分别表示这三项子任务,则人有六种可能的次序:DLR、LDR、LRD、DRL、RDL和RLD。通常限定“先左后右”,即子任务②在子任务③之前完成,这样就只剩下前三种次序,按这三种次序进行的遍历分别称为先根遍历(或前序遍历)、中根(或中序)遍历、后根(或后序)遍历。三种遍历方法的定义如下:

先根遍历 若需遍历的二叉树为空,执行空操作;否则,依次执行下列操作:

①访问根结点;

②先根遍历左子树;

③先根遍历右子树。

中根遍历 若需遍历的二叉树为空,执行空操作,否则,依次执行下列操作:

①中根遍历左子树;②访问根结点;③中根遍右子树。

后根遍历 若需遍历的二叉树为空,执行空操作,否则,依次执行下列操作:

①后根遍历左子树。②后根遍历右子树。③访问根结点。

显然,上述三种遍历方法的区别在于执行子任务“访问根结点”的“时机”不同;最先(最后、在中间)执行此子任务,则为先根(后根、中根)遍历。

按某种遍历方法遍历一棵二叉树,将得到该二叉树上所有结点的访问序列。

6.树

树是一种常用的数据结构。为了适应各种应用问题的需要,多种不同的存储结构也相应地建立起来。下面介绍树的三种常用存储结构。

(1)孩子链表表示法

孩子链表表示法是树的一种链式存储结构。与二叉树的二叉链表存储方法类似,孩子链表表示法的基本思想是:树上的一个结点的内容(数据元素)以及指向该结点所有孩子的指针存储在一起以便于运算的实现。由于树上的结点的度(孩子数)没有限制,而且各个结点的度可能相差很大,一种自然的表示方法是为树上的每个结点X建立一个“孩子链表”,以便存储X中的数据元素和指向X的所有孩子的指针。一个孩子链表是一个带头结点的单链表,单链表的头结点含两个域:数据域和指针域。其中,数据域用于存储结点X中的数据元素;指针域用于存储指向该单链表中第一个表结点(首结点)的指针。为了检索方便,所有头结点组织成一个数组,称为表头数组。对每个结点X的孩子链表来说,其中的所有表结点也含两个域,孩子域(即数据域)和指针域。第i个表结点的孩子域存储X的第i个孩子在头结点数组中的下标值。

(2)孩子兄弟链表表示法

孩子兄弟链表中所有存储结点的形式相同,均含三个域:数据域———用于存储树上的结点中的数据元素;孩子域———用于存储指向本结点第一个孩子的指针;兄弟域———用于存放指向本结点下一个兄弟的指针。

值得注意的是,孩子兄弟链表的结构形式与二叉链表完全相同;但存储结点中指针的含义不同。二叉链表中存储结点的左、右指针分别指向左、右孩子;而孩子兄弟链表中存储结点的两个指针分别指向“长子”和“大弟”。

在孩子兄弟链表表示法中,结点形式统一,结点间的联系比较简捷。同时,在这种存储结构上容易实现树数据结构的大多数运算。

(3)双亲表示法

树上每个结点的孩子可以有任意多个,但双亲只有一个。因此,**指向双亲的指针而将树中所有结点组织在一起形成一种存储结构是十分简法的。树的这种存储表示方法称为双亲表示法。在双亲表示法下,每个存储结点由两个域组成:数据域———用于存储树上结点中的数据元素;“指针”域———用于指示本结点之双亲所在的存储结点。值得注意的是,“指针”域的类型定义可以有两种选择。第一种是将其定义为高级语言(如C语句)中的指针类型。**将存储结点中的指针域定义为高级语言中的指针类型,就得到各种链式存储结构,如单链表、二叉链表、孩子链表等等。第二种选择是将“指针”域定义为整型、子界型等型。严格地说,无论选择上述哪种定义,得到的都是链式存储结构,因为在这两种定义之下,各存储结点之间的联结是**“指针”完成的,而且这些指针反映了结点之间的逻辑关系。

为了区别这两种链式结构,通常将指针域定义为高级语言中的指针类型的各种链式存储结构(如单链表、二叉链表等等)称为“动态链表”,相应的指针称为“动态指针”;将指针域定义为整型、子界型等类型的各种键式存储结构称为“静态链表”,相应的“指针”称为:“静态指针”。动态链表中的结点是**高级语言中的标准过程例如C语言的库函数malloc(size)动态(即运行期间)生成的(动态链表由此得名),无需事先规定链表的容量,因此动态链表的大小是动态变化的。相反,静态链有的容量必须事先说明,因而其大小是固定的。然而,在某些情况下,特别是当结点数固定不变且可事先确定时,采用静态链表往往更加方便、直观。

静态双亲链表由一个一维数组树成。数组的每个分量包含两个域:数据域和双亲域。数据域用于存储树上一个结点中的数据元素;双亲域用于存放本结点的双亲结点在数组中的序号(下标值)。来源:www.examda.com

7.树的遍历

与二叉树类似,遍历是树的一种重要运算。树的主要遍历方法有以下三种。

(1)先根遍历若树非空,则

①访问根结点;

②依次先根遍历根的各个子树T 1 ,…,T m 。

(2)后根遍历若树非空,则

①依次先根遍历根的各个子树T 1 ,…,T m 。②访问根结点;

(3)层次遍历

①若树非空,访问根结点;

②若第1,…,i(i≥1)层结点已被访问,且第i+1层结点未访问,则从左到右依次访问第i+1层结点。

显然,按层次遍历所得的结点访问序列中,各结点的序号与按层编号所得的编号一致。

8.树与二叉树之间的转换

一般树转换为二叉树的基本思想是:将树中每个结点用两个链接表示就可以了,一个指向它最左边的孩子,另一个指向它右边的一个兄弟,从图形上看,具体步骤是:

①加线:在兄弟结点直接加一虚线;

②抹线:对每个结点,除了其最左的一个孩子外,抹去该结点原来与其余孩子之间的边线;

③旋转:将新加上的虚线改为实线,并将虚线以及有关的实线顺时钟旋转45度。

二叉树还原为一般树的步骤是:

①加线:若某结点是一父结点的左孩子,则将该结点的右孩子以及沿着右链搜索到的所有右孩子结点都用线与那个父结点连接起来;

②抹线:抹去原二叉树中所有结点与其右孩子的连线;

③旋转:将虚线及有关实线逆时钟旋转约45度,并将几个结点按层次排列。

9.二叉树与森林之间的转换

森林转换为二叉树的步骤是:

①将森林中的每棵树转换为二叉树;

②森林中第一棵树的根结点就是转换后二叉树的根结点,依次将后一棵树作为前一棵树根结点的右子树。

二叉树转换为森林的步骤是:

①森林第一棵树的根就是二叉树的根;

②二叉树的左子树转换为森林的第一棵树,二叉树的右子树对应于森林中其余的树;③二叉树右子树的根结点作为余下树中第一棵树的根结点……,以此类推。

2829f2ca24f0d0090cbba57f30759f23.png

2017年全国计算机等级考试四级复习纲要:树型结构.doc

下载Word文档到电脑,方便收藏和打印[全文共7558字]

编辑推荐:

8b95f2eb3d3f7ce4dc3bf1178c74941e.png

8b95f2eb3d3f7ce4dc3bf1178c74941e.png

8b95f2eb3d3f7ce4dc3bf1178c74941e.png

8b95f2eb3d3f7ce4dc3bf1178c74941e.png

8b95f2eb3d3f7ce4dc3bf1178c74941e.png

下载Word文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值