(六)树和二叉树

追风赶月莫停留,平芜尽处是春山。                                                     

                                                                                                            ——文记

        前面我写到了关于栈与队列、串、数组与广义表,它们都是线性结构,然后从这篇文章开始我将复习非线性结构——树与图。线性结构中节点间具有唯一前驱、唯一后继关系,而非线性结构中结点间前驱与后继的关系不拥有唯一性。其中,在树结构中,结点间关系是前驱唯一而后继不唯一,即结点之间是一对多的关系。直观来看,树结构是指具有分支关系的结构。应用于大量数据处理(如文件系统、编译系统、目录组织等)。

目录

树的定义与基本术语

1.树的基本概念

2.树的图解表示法

3.树的相关术语

4.树的抽象数据类型  

二叉树

1. 二叉树的定义与基本操作

2. 二叉树的性质

3. 二叉树的存储结构

4.二叉树的遍历与线索化

树、森林和二叉树的关系 

哈夫曼树及其应用 

总结与提高 


树的定义与基本术语

1.树的基本概念

树定义:是n(n≥0)个结点的有限集合T。当n=0时,称为空树;当n>0时,该集合满足如下条件:

(1) 其中必有一个称为根(root)的特定结点,它没有直接前驱,但有零个或多个直接后继。

(2) 其余n-1个结点可以划分成m(m≥0)个互不相交的有限集T1,T2,T3,…,Tm,其中Ti又是一棵树,称为根root的子树。每棵子树的根结点有且仅有一个直接前驱,可有零个或多个直接后继。

一棵树的逻辑结构图为:

从图中可以看出它好象一棵倒栽的树。


2.树的图解表示法

1)倒置树结构(树形表示法)

2)文氏图表示法(嵌套集合形式)

3)广义表形式(嵌套扩号表示法)

4)凹入表示法


3.树的相关术语

 


4.树的抽象数据类型  

数据对象D:一个集合,该集合中的所有元素具有相同的特性。

数据关系R:若D为空集,则为空树。若D中仅含有一个数据元素,则R为空集,否则R={H},H是如下的二元关系:

(1) 在D中存在唯一的称为根的数据元素root,它在关系H下没有前驱。

(2) 除root以外,D中每个结点在关系H下都有且仅有一个前驱。

基本操作:

(1)InitTree(Tree): 将Tree初始化为一棵空树。

(2) DestoryTree(Tree): 销毁树Tree。

(3) CreateTree(Tree): 创建树Tree。

(4) TreeEmpty(Tree): 若Tree为空,则返回TRUE,否则返回FALSE。

(5) Root(Tree): 返回树Tree的根。

(6) Parent(Tree,x): 树Tree存在,x是Tree中的某个结点。若x为非根结点,则返回它的双亲,否则返回“空”。

(7) FirstChild(Tree,x): 树Tree存在,x是Tree中的某个结点。若x为非叶子结点,则返回它的第一个孩子结点,否则返回“空”。

(8) NextSibling(Tree,x): 树Tree存在,x是Tree中的某个结点。若x不是其双亲的最后一个孩子结点,则返回x后面的下一个兄弟结点,否则返回“空”。

(9) InsertChild(Tree,p,Child): 树Tree存在,p指向Tree中某个结点,非空树Child与Tree不相交。将Child插入Tree中,做p所指向结点的子树。

(10) DeleteChild(Tree,p,i): 树Tree存在,p指向Tree中某个结点,1≤i≤d,d为p所指向结点的度。删除Tree中p所指向结点的第i棵子树。

(11) TraverseTree(Tree,Visit()): 树Tree存在,Visit()是对结点进行访问的函数。按照某种次序对树Tree的每个结点调用Visit()函数访问一次且最多一次。若Visit()失败,则操作失败。

二叉树

1. 二叉树的定义与基本操作

定义:我们把满足以下两个条件的树型结构叫做二叉树(Binary Tree):

(1)每个结点的度都不大于2;

(2)每个结点的孩子结点次序不能任意颠倒。

 二叉树的基本操作:

(1)Initiate(bt):将bt初始化为空二叉树。

(2) Create(bt):创建一棵非空二叉树bt。

(3) Destory(bt): 销毁二叉树bt。

(4) Empty(bt): 若bt为空,则返回TRUE,否则返回FALSE。

(5) Root(bt): 求二叉树bt的根结点。若bt为空二叉树,则函数返回“空”。

(6) Parent(bt,x):求双亲函数。求二叉树bt中结点x的双亲结点。若结点x是二叉树的根结点或       二叉树bt中无结点x,则返回“空”。

(7) LeftChild(bt,x):求左孩子。若结点x为叶子结点或x不在bt中,则返回“空”。

(8) RightChild(bt,x):求右孩子。若结点x为叶子结点或x不在bt中,则返回“空”。

(9) Traverse(bt): 遍历操作。按某个次序依次访问二叉树中每个结点一次且仅一次。

(10) Clear(bt):清除操作。将二叉树bt置为空树。


2. 二叉树的性质

性质1:在二叉树的第i层上至多有2i-1个结点(i≥1)。

 性质2:深度为k的二叉树至多有2k-1个结点(k≥1)。

 性质3:对任意一棵二叉树T,若终端结点数为n0,而其度数为2的结点数为n2,则n0= n2+1 。

 两种特殊的二叉树:

满二叉树:深度为k且有2k-1个结点的二叉树。在满二叉树中,每层结点都是满的,即每层结点都具有最大结点数。

 

 完全二叉树:

深度为k,结点数为n的二叉树,如果其结点1~n的位置序号分别与满二叉树的结点1~n的位置序号一一对应,则为完全二叉树

 关系:满二叉树必为完全二叉树,而完全二叉树不一定是满二叉树。

性质4:具有n个结点的完全二叉树的深度为㏒2n+1。 

 性质5:对于具有n个结点的完全二叉树,如果按照从上到下和从左到右的顺序对二叉树中的所有结点从1开始顺序编号,则对于任意的序号为i的结点有:


3. 二叉树的存储结构

二叉树的结构是非线性的,每一结点最多可有两个后继。

二叉树的存储结构有两种:顺序存储结构和链式存储结构。

(1)顺序存储结构:是用一组连续的存储单元来存放二叉树的数据元素 。


对于一般的二叉树,我们必须按照完全二叉树的形式来存储,就会造成空间的浪费。单支树就是一个极端情况。


(2). 链式存储结构

对于任意的二叉树来说,每个结点只有两个孩子,一个双亲结点。我们可以设计每个结点至少包括三个域:数据域、左孩子域和右孩子域:

 用C语言描述定义二叉树的二叉链表结构如下 :

typedef struct Node
{DataType data;
strct Node * LChild;
struct Node * RChild;
   }BiTNode, *BiTree;

 结论:若一个二叉树含有n个结点,则它的二叉链表中必含有2n个指针域,其中必有n+1个空的链域。


4.二叉树的遍历与线索化

 二叉树的遍历

二叉树的遍历:指按一定规律对二叉树中的每个结点进行访问且仅访问一次。

二叉树的基本结构由根结点、左子树和右子树组成

 用L、D、R分别表示遍历左子树、访问根结点、遍历右子树,那么对二叉树的遍历顺序就可以有:

访问根,遍历左子树,遍历右子树(记做DLR)。

访问根,遍历右子树,遍历左子树(记做DRL)。

遍历左子树,访问根,遍历右子树(记做LDR)。

遍历左子树,遍历右子树,访问根 (记做LRD)。

遍历右子树,访问根,遍历左子树 (记做RDL)。

遍历右子树,遍历左子树,访问根 (记做RLD)。

 在以上六种遍历方式中,如果我们规定按先左后右的顺序,那么就只剩有 DLR 、LDR  和LRD三种。根据对根的访问先后顺序不同,分别称DLR为先序遍历或先根遍历;LDR为中序遍历(对称遍历);LRD为后序遍历。

注意:先序、中序、后序遍历是递归定义的,即在其子树中亦按上述规律进行遍历。

三种遍历方法的递归定义:

(1)先序遍历(DLR)操作过程:

若二叉树为空,则空操作,否则依次执行如下操作:

①访问根结点;

②按先序遍历左子树;

③按先序遍历右子树。

(2)中序遍历(LDR)操作过程

若二叉树为空,则空操作,否则依次执行如下操作:

①按中序遍历左子树;

②访问根结点;

③按中序遍历右子树。

(3)后序遍历(LRD)操作过程:

若二叉树为空,则空操作,否则依次执行如下操作:

①按后序遍历左子树;

②按后序遍历右子树;

③访问根结点。

 对于如下图的二叉树,其先序、中序、后序遍历的序列为:

先序遍历: A、B、D、F、G、C、E、H 。

中序遍历: B、F、D、G、A、C、E、H 。

后序遍历: F、G、D、B、H、E、C、A 。

  遍历算法应用

  基于栈的递归消除

 线索二叉树

 由遍历序列确定二叉树

树、森林和二叉树的关系 

哈夫曼树及其应用 

总结与提高  

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

登登登__

期待每一份真诚

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值