第4章树结构介绍
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2018年10月14日
第27页
(1) Initiate(bt):建立一棵空的二叉树bt,并返回bt。
【算法 4-1(a)】建立一棵空的带头结点的二叉树 BiTree Initiate () //初始建立一棵带头结点的二叉树 { BiTNode *bt; bt=(BiTNode *)malloc(sizeof(BiTNode)); bt->lchild=NULL; bt->rchild=NULL; return bt; } 若要建立不带头结点的二叉树,可描述如下: 【算法 4-1(b)】建立一棵空的不带头结点的二叉树 BiTree Initiate () //初始建立一棵不带头结点的二叉树 { BiTNode *bt; bt=NULL; return bt; }
【算法 4-5】先序遍历二叉树的递归算法 void PreOrder(BiTree bt) { if (bt==NULL) return; //递归调用的结束条件 Visit(bt) ; //访问根结点 PreOrder(bt->lchild); //先序递归遍历bt的左子树 PreOrder(bt->rchild); //先序递归遍历bt的右子树 }
2018年10月14日
第16页
4.2.3 二叉树的存储 1.顺序存储结构
所谓二叉树的顺序存储,是用一组连续的存储单元 存放二叉树中的结点。一般是按照二叉树结点从上至下、 从左到右的顺序存储。
2018年10月14日
第17页
•下面给出一棵完全二叉树的顺序存储示意。
2018年10月14日
第18页
• 对于一般的二叉树,如果仍按从上至下和从左到右的顺序将
2018年10月14日
第3页
⒊教学重点:
二叉树的定义、逻辑特点及性质;二叉树的存 储结构;二叉树的遍历方法及其算法;以遍历为基 础在二叉树上实现的几种运算;哈夫曼树和哈夫曼 算法;树的存储结构;森林与二叉树的转换。
⒋教学难点:
二叉树的递归定义;二叉树链式存储结构的组织 方式;三种遍历的算法;二叉树上的复杂运算;哈 夫曼算法及其应用;
2018年10月14日
4.1 引言
4.1.1 问题提出
第4页
问题1:组织结构层次关系的存储与查找。 问题2:家族族谱中家族成员之间的关系表示与查找。 问题3:图书馆中图书的分类关系的建立。 。。。。。。
2018年10月14日
4.1.2 相关概念
1.树的定义
第5页
树(Tree)是n(n≥0)个有限数据元素的集合。当n =0时,称这棵树为空树。在一棵非空树T中: (1) 有一个特殊的数据元素称为树的根结点,根结点没 有前驱结点。 (2) 若 n>1 ,除根结点之外的其余数据元素被分成 m (m>0)个互不相交的集合T1, T2, …, Tm,其中每一 个集合Ti(1≤i≤m)本身又是一棵树。树T1, T2, …, Tm 称为这个根结点的子树。
2018年10月14日
第21页
2.链式存储结构
(1)二叉链表存储
2018年10月14日
第22页
下图(a)给出一棵二叉树的二叉链表存储表示。二叉链 表也可以带头结点的方式存放,如图(b)所示。
2018年10月14日
第23页
二叉树的二叉链表存储结构可描述为:
typedef struct bitnode { datatype data; struct bitnode *lchild;*rchild; //左右孩子指针 } BiTNode, *BiTree; 定义一个指向二叉树的指针变量:BiTree t;
第4章 树结构
第2页
1.教学内容
二叉树和树的概念、二叉树的遍历及其应用、线 索二叉树、哈夫曼树及哈夫曼编码、树和森林与二叉 树之间的转换、树或森林的遍历。
⒉教学目的
深刻理解二叉树的定义、性质及其存储方法; 熟练掌握二叉树的二叉链表存储方式、结点结构和类 型定义;掌握二叉树的三种遍历算法;了解二叉树的 线索化方法;灵活运用二叉树的遍历方法解决相关的 应用问题; 掌握森林与二叉树间的相互转换;掌握树 和森林的遍历方法。
2018年10月14日
第14页
4.2.2 二叉树的主要性质
性质1 一棵非空二叉树的第i层上最多有2i-1个结点(i≥1)。 性质2 一棵深度为k的二叉树中,最多具有2k-1个结点。
性质3 对于一棵非空的二叉树,若叶子结点数为n0,度数为2
的结点数为n2,则有:n0=n21。 性质4 具有n个结点的完全二叉树的深度k为: log2n+1
2018年10月14日
第9页
(9)树的度 (10)有序树和无序树 (11)森林
2018年10月14日
4.2.1 二叉树的概念
1.二叉树的定义
4.2 二叉树
第10页
2018年10月14日
第11页
2.二叉树的相关术语 (1) 满二叉树。
2018年10月14日
第12页
(2) 完全二叉树。
2018年10月14日
(4) InsertR(bt,x,parent):功能类同于(3) ,算法略。
2018年10月14日
第30页
(5)DeleteL(bt,parent):在二叉树bt中删除parent的左子树
【算法 4-4】在二叉树bt中删除parent的左子树 BiTree DeleteL(BiTree bt,BiTree parent) {BiTree p; if (parent==NULL||parent->lchild==NULL) { printf("\n删除出错"); return NULL; } p=parent->lchild; parent->lchild=NULL; free(p); //当*p为非叶子结点时,这样删除仅释放了所删子树根结点的空间, //若要删除子树分支中的结点,需用后面介绍的遍历操作来实现。 return bt; }
2018年10月14日
第6页
2018年10月14日
第7页
树具有下面两个特点: ⑴树的根结点没有前驱结点,除根结点之外的所有结点 有且只有一个前驱结点。 ⑵树中所有结点可以有零个或多个后继结点。 由此特点可知,下图所示的都不是树结构。
2018年10月14日
Байду номын сангаас 第8页
3.相关术语
(1) 结点的度 (2) 叶结点 (3) 分支结点 (4) 左孩子、右孩子、双亲、兄弟 (5) 路径、路径长度 (6) 祖先、子孙 (7) 结点的层数 (8) 树的深度
若以D、L、R分别表示访问根结点、遍历根结点的左子树、 遍历根结点的右子树, 如果限定先左后右,则有三种方式, 即: DLR(称为先序遍历) LDR(称为中序遍历) LRD(称为后序遍历) 。
2018年10月14日
第33页
1.先序遍历
先序遍历的递归过程为:若二叉树为空,遍历结束。否则, (1) 访问根结点; (2) 先序遍历根结点的左子树; (3) 先序遍历根结点的右子树。
2018年10月14日
第29页
(3) InsertL(bt, x, parent):在二叉树bt中的parent所指结 点和其左子树之间插入数据元素为x的结点
【算法4-3】在二叉树bt中的parent所指结点和其左子树之间插入数据元素为x的 结点 BiTree InsertL(BiTree bt,elemtype x,BiTree parent) {BiTree p; if (parent==NULL) {printf("\n插入出错"); return NULL; } if ((p=(BiTNode *)malloc(sizeof(BiTNode)))==NULL) return NULL; p->data=x; p->lchild=NULL; p->rchild=NULL; if (parent->lchild==NULL) parent->lchild=p; else {p->lchild=parent->lchild; parent->lchild=p; }
树中的结点顺序存储在一维数组中,则数组元素下标之间的关 系不能够反映二叉树中结点之间的逻辑关系,只有增添一些并 不存在的空结点,使之成为一棵完全二叉树的形式,然后再用 一维数组顺序存储。
2018年10月14日
第19页
极端情况是单支树,如一棵深度为k的右单支树,只 有k个结点,却需分配2k-1个存储单元。
显然,对于需增加许多空结点才能将一棵二叉树改 造成为一棵完全二叉树的存储时,会造成空间的大量浪 费,不宜用顺序存储结构。
2018年10月14日
第20页
二叉树的顺序存储结构可描述为: #define MAXNODE 1024 //二叉树的最大结点数,可根据实际情况进行修改 typedef datatype SqBiTree[MAXNODE]; //0号单元存放根结点 定义一个顺序存储的二叉树变量:SqBiTree bt; 即将bt为含有MAXNODE个datatype类型元素的一维数组。
第13页
3.二叉树的基本操作
(1) Initiate(bt) (2) Create(x, lbt, rbt) (3) InsertL(bt, x, parent) (4) InsertR(bt, x, parent) (5) DeleteL(bt, parent) (6) DeleteR(bt, parent) (7) Search(bt, x) (8) Traverse(bt)
2018年10月14日
第15页
性质5: 对于具有n个结点的完全二叉树,如果按照从上至下 和从左到右的顺序对二叉树中的所有结点从 1开始顺序编号 ,则对于任意的序号为i的结点,有: ⑴如果i>1,则序号为i的结点的双亲结点的序号为 i/2;如 果i=1,则序号为i的结点是根结点,无双亲结点。 ⑵如果2i≤n,则序号为i的结点的左孩子结点的序号为2i;如 果2i>n,则序号为i的结点无左孩子。 ⑶如果2i +1≤n ,则序号为i 的结点的右孩子结点的序号为 2i +1;如果2i+1>n,则序号为i的结点无右孩子。 此外,若对二叉树的根结点从 0 开始编号,则相应的 i 号结 点的双亲结点的编号为 (i-1)/2,左孩子的编号为 2i+1,右 孩子的编号为2i+2。
2018年10月14日
第34页
对于上图所示的二叉树,按先序遍历所得到的 结点序列为:
ABDGCEF
2018年10月14日
第35页
2.中序遍历
中序遍历的递归过程为:若二叉树为空,遍历结束。否则, (1) 中序遍历根结点的左子树; (2) 访问根结点; (3) 中序遍历根结点的右子树。
【算法 4-6】中序遍历二叉树的递归算法 void InOrder(BiTree bt) {if (bt==NULL) return; //递归调用的结束条件 InOrder(bt->lchild); //中序递归遍历bt的左子树 Visit(bt); //访问根结点 InOrder(bt->rchild); //中序递归遍历bt的右子树 }
2018年10月14日
第24页
(2)三叉链表存储 每个结点由四个域组成,具体结构为:
2018年10月14日
第25页
下图给出一棵二叉树的三叉链表存储示意图。
2018年10月14日
第26页
4.2.4 二叉树基本运算的实现
算法的实现依赖于具体的存储结构,当二叉树采用不同的 存储结构时,上述各种操作的实现算法是不同的。 下面讨论基于二叉链表存储结构的上述操作的实现算法。
(6) DeleteR(bt,parent):算法略。
2018年10月14日
第31页
4.3 二叉树的遍历
二叉树的遍历是指按照某种顺序访问二叉树中的每 个结点,使每个结点被访问一次且仅被访问一次。二 叉树遍历是二叉树中最重要最基本的运算。
2018年10月14日
第32页
4.3.1
递归方法实现二叉树的三种遍历
2018年10月14日
第28页
(2) Create(x,lbt,rbt):生成一棵以x为根结点的数据域值 以lbt和rbt为左右子树的二叉树。
【算法 4-2】生成一棵以x为根结点的数据域值以lbt和rbt为左右子树的二叉树 BiTree Create(elemtype x, BiTree lbt, BiTree rbt) {BiTree p; if ((p=(BiTNode *)malloc(sizeof(BiTNode)))==NULL) return NULL; p->data=x; p->lchild=lbt; p->rchild=rbt; return p; }