数据结构06树和二叉树

第六章 树和二叉树

6.1 树的定义和基本术语

树 Tree 是n个结点的有限集。

任意一棵非空树中:

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

(2)当n>1时,其余结点可分为m(m>0)个互不相交的有限集T1,T2,...,Tm,其中,每一个集合本身又是一棵树,并且称为根的子树(SubTree)。

 

结点:包含一个数据元素及若干指向其子树的分支。

结点的度(degree):结点拥有的子树数。

叶子(Leaf)/终端结点:度为0的结点。

分支结点/非终端结点:度不为0的结点。 除根结点外,分支结点也称为内部结点。

孩子(Child):结点的子树的根称为该结点的孩子。

双亲(Parent):该结点称为孩子的双亲。

兄弟(Sibling):同一个双亲的孩子之间互称兄弟。

祖先:从根到该结点所经的所有结点。

子孙:以某结点为根的子树中的任一结点。

层次(Level):根为第一层,根的孩子为第二层。

若某结点在第l层,则其子树的根在第l+1层。

其双亲在同一层的结点互为堂兄弟

深度(Depth)/高度:树中结点的最大层次。

 

有序树:树中结点的各子树从左至右是有次序的。

无序树:树中结点的各子树从左至右是无次序的。

森林(Forest):m棵互不相交的树的集合。

对树中每个结点而言,其子树的集合即为森林。

 

6.2 二叉树

二叉树 Binary Tree

每个结点至多只有两棵子树,并且二叉树的子树有左右之分,其次序不能任意颠倒。

 

二叉树的5种基本形态:

空二叉树

仅有根节点

右子树为空

左子树为空

左右子树均非空

 

二叉树的性质:

1、在二叉树第i层上至多有2^(i-1)个结点。

2、深度为k的二叉树至多有2^k-1个结点。

3、对任何一棵二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0=n2+1

结点:n=n0+n1+n2

入度:n=n1+2n2+1

 

 

满二叉树:一棵深度为k且有2^k-1个结点的二叉树称为满二叉树。

特点:每一层上的结点数都是最大结点数。

可以对满二叉树的结点进行连续编号,约定编号从根结点起,自上而下,自左至右。

 

由此可引出完全二叉树的定义:

深度为k的,有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中的编号从1至n的结点一一对应时,称之为完全二叉树。

特点:

(1)叶子结点只可能在层次最大的两层上出现;

(2)对任一结点,若其右分支下的子孙的最大层次为l,则其左分支下的子孙的最大层次必为l或l+1。

 

完全二叉树的两个重要性质:

1、具有n个结点的完全二叉树的深度为

2、对于完全二叉树的编号:

(1)如果i=1,则结点i是二叉树的根,无双亲;如果i>1,则其双亲结点是i/2;

(2)如果2i>n,则i结点无左孩子;否则,其左孩子为2i;

(3)如果2i+1>n,则i结点无右孩子;否则,其右孩子为2i+1。

 

 

二叉树的存储结构:

(1)顺序存储结构:完全二叉树。

(2)链式存储结构:

二叉链表:左孩子、右孩子

三叉链表:左孩子、右孩子、父结点

 

二叉链表存储结构的许多基本操作都采用了递归函数,因为二叉树的层数是不定的,正确采用递归函数可简化编程。
递归函数特点:1、降阶;2、出口。

 

 

在含有n个结点的二叉链表中有n+1个空链域。

可以利用这些空链域存储其他有用信息,从而得到另一种链式存储结构——线索链表

 

6.3 遍历二叉树和线索二叉树

6.3.1 遍历二叉树

将非线性的二叉树结构线性化。

Traversing binary tree

二叉树是由三个基本单元组成:根节点、左子树、右子树

限定先左后右,有三种遍历方式:先序遍历、中序遍历、后续遍历

对二叉树做中序遍历和先序遍历(或者中序遍历和后续遍历),就可以确定二叉树的形状。

 

先序遍历二叉树:

若二叉树为空,则空操作;否则

1、访问根节点;

2、先序遍历左子树;

3、先序遍历右子树。

 

中序遍历二叉树:

若二叉树为空,则空操作;否则

1、中序遍历左子树;

2、访问根节点;

3、中序遍历右子树。

 

后序遍历二叉树:

若二叉树为空,则空操作;否则

1、后序遍历左子树;

2、后序遍历右子树;

3、访问根节点。

 

非递归中序遍历二叉树

 

 

 

二叉树表达式:

前缀表达式-波兰式

中缀表达式

后缀表达式-逆波兰式

 

还可以从上到下,从左到右按层次进行遍历。即层序遍历。

时间复杂度O(n)

空间复杂度O(n)

 

链式结构先序构造二叉树时,要把度数为1的结点和叶子结点的无用指针置空。

 

 

6.3.2 线索二叉树

遍历二叉树是以一定规则将二叉树中结点排列成一个线性序列,得到二叉树中结点的先序序列或中序序列或后序序列。即对一个非线性结构进行线性化操作。

在有n个结点的二叉链表中必定存在n+1个空链域。

利用这些空链域来存储结点的前驱和后继信息。

规定如下:

若结点有左子树,则lchild指向其左孩子,否则,指向其前驱;

若结点有右子树,则rchild指向其右孩子,否则,指向其后继。

 

增加两个标志域:LTag  RTag   0(Link)指向左右孩子,1(Tread)指向前驱后继。

指向前驱和后继的指针,叫做线索

线索二叉树(Threaded Binary Tree)

 

对二叉树以某种次序遍历使其变为线索二叉树的过程叫做线索化

在线索树上进行遍历,只要先找到序列中的第一个结点,然后依次找结点后继直至其后继为空时为止。

 

中序线索树:

后继:

若其右标志为1,右链直接指示后继;

非终端的后继:遍历右子树时,第一个访问的结点为后继,即右子树中最左下的结点。

前驱:

若其左标志为1,左链直接指示前驱;

非终端的前驱:遍历左子树时,最后一个访问的结点为前驱,即左子树中最右下的结点。

 

后序线索树:

后继:

若为根节点,后继为空;

若结点为双亲右孩子,或为左孩子且双亲无右孩子,则其后继为双亲;

若结点为左孩子且双亲有右孩子,则后继为双亲右子树上按后序遍历列出的第一个结点。

在后序线索化树上找后继时需知道结点双亲,即需带标志域的三叉链表作为存储结构。

 

 

中序线索二叉树的遍历,虽然时间复杂度为O(n),但常数因子要小于普通二叉树。

若某程序对二叉树需经常遍历,或查找结点的前驱或后继,应采用线索链表作存储结构。

 

可以在二叉树的线索表上添加一个头结点,令其lchild指向二叉树根结点,rchild指向中序遍历时访问的最后一个结点;令二叉树中序序列中的第一个结点的lchild域指针和组后一个结点rchild域指针指向头结点。

 

线索化的实质是将二叉树链表中的空指针改为指向前驱或后继的线索。

线索化的过程即为在遍历的过程中修改空指针的过程。

附设一个指针pre始终指向前一个访问的结点,指针p指向当前访问结点。

指针pre指向的是p的前驱,指针p指向的是pre的后继。

 

6.4 树和森林

6.4.1 树的存储结构

1、双亲表示法

以一组连续空间存储树的结点,同时在每个结点中附设一个指示器指示其双亲结点的位置。

这种表示法利用了每个结点(根结点除外)只有唯一双亲的性质。

求孩子结点时需要遍历整个结构。

 

2、孩子表示法

把每个结点的孩子结点排列起来,看成是一个线性表,以单链表作为存储结构,则n个结点有n个孩子链表(叶子的孩子链表为空表)。

而n个头指针又组成一个线性表,为了便于查找,可采用顺序存储结构。

孩子表示法便于那些涉及孩子的操作。

 

可以把双亲表示法和孩子表示法结合起来,即将双亲表示和孩子链表合在一起。

 

3、 孩子兄弟表示法

二叉链表作为树的存储结构。

结点的两个链域分别指向该结点的第一个孩子结点和下一个兄弟结点。

分别命名为firstchild域和nextsibling域。

任何一棵和树对应的二叉树,其右子树必空。

 

6.4.2 森林与二叉树的转换

把森林中第二棵树的根结点看成是第一棵树的根结点兄弟,可以导出森林和二叉树的对应关系。

 

6.4.3 树和森林的遍历

两种方式:

先根遍历,对应二叉树的先序遍历;

后根遍历,对应二叉树的后序遍历。

 

6.6 哈夫曼树及其应用

6.6.1 最优二叉树(哈夫曼树)

路径:从一个结点到另一个结点之间的分支构成两个结点间的路径。

路径长:路径上的分支数目。

树的路径长度:从树根到每一个叶子结点的路径长度之和。

带权路径长度:路径长度与结点权值的乘积。

树的带权路径长度:所有叶子结点的带权路径长度之和。

假设有n个权值,对应n个叶子结点,带权路径长度WPL最小的二叉树称为最优二叉树哈夫曼树

 

最优二叉树特点:

权值越小的结点,其到根结点的路径越长。

最优二叉树的左右子树是可以互换的,不影响树的带权路径长度。

 

哈夫曼算法:

(1)根据给定的n个权值{W1, W2, ..., Wn}构成n棵二叉树的集合F={T1, T2, ..., Tn},其中每棵二叉树Ti中只用一个带权为Wi的根结点,其左右子树均空;

(2)在F中选取两棵根结点的权值最小的树作为左右子树构造一棵新的二叉树,且新的二叉树的根结点的权值为左右子树根结点权值之和;

(3)在F中删除这两棵树,并将新的树加入F中;

(4)重复(2)(3),直至只含一棵树为止。

 

6.6.2 哈夫曼编码

若想设计长短不等的编码,必须是任一个字符的编码都不是另一个字符的编码的前缀,这种编码称作前缀编码

 

可以利用二叉树来设计二进制的前缀编码。

约定左分支为0,右分支为1。

从根结点到叶子结点的路径上的分支01串,即为该叶子结点的前缀编码。

 

设计电文总长最短的二进制前缀编码即为

以n种字符出现的频率作权,设计一棵哈夫曼树,由此得到的二进制前缀码便称为哈夫曼编码。

哈夫曼树中没有度为1的结点。(这类树又称为严格/正则二叉树)

则一棵有n个叶子结点的哈夫曼树共有2n-1个结点,可以存储在一个大小为2n-1的一维数组中。

 

 

 

6.7 回溯法与树的遍历

试探与回溯:在约束条件下,先序遍历一颗状态树。

在程序设计问题中,有相当一类求一组解、或求全部解、或求最优解的问题,这类问题不是根据某种确定的计算法则,而是利用试探和回溯(Backtracking)的搜索技术求解。

回溯法是设计递归过程的一种重要方法,它的求解过程实质上是一个先序遍历一棵“状态树”的过程,这棵树不是遍历前预先建立的,而是隐含在遍历过程中,认识到这一点,许多问题就迎刃而解了。

 

很多问题用回溯和试探求解时,描述求解过程的状态树不是一棵满的多叉树。

当试探过程中出现的状态和问题所求解产生矛盾时,不再继续试探下去,这时出现的叶子结点不是问题的解的终结状态。

这类问题的求解过程可看成是在约束条件下进行先序遍历,并在遍历过程中剪去那些不满足条件的分支。

 

八皇后问题:

任何两个棋子不在同一行、同一列、同一斜线。

求所有合法布局的过程即为在上述约束条件下先根遍历状态树的过程。

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/387206.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2019.03.20 mvt,Django分页

MVT模式 MVT各部分的功能: M全拼为Model,与MVC中的M功能相同,负责和数据库交互,进行数据处理。 V全拼为View,与MVC中的C功能相同,接收请求,进行业务处理,返回响应。 T全拼为Tem…

CountDownLatch,CyclicBarrier和Semaphore

在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法。以下是本文目录大纲:一.CountDownLatch用法二.CyclicBarrie…

数据结构07排序

第十章内部排序 10.1 概述 排序就是把一组数据按关键字的大小有规律地排列。经过排序的数据更易于查找。 排序前KiKj,且Ki在前: 排序方法是稳定的,若排序后Ki在前; 排序方法是不稳定的,如排序后Kj在前。 分类: 内…

数据结构08查找

第九章 查找 另一种在实际应用中大量使用的数据结构--查找表。 所谓查找,即为在一个含有众多的数据元素的查找表中找出某个“特定的”数据元素。 查找表 search table 是由同一类型的数据元素构成的集合。集合中的数据元素之间存在着完全松散的关系,故…

下载Centos7 64位镜像

下载Centos7 64位镜像 1.打开Centos官网 打开Centos官方网站地址:https://www.centos.org/,点击Get CentOS Now 2.点击Minimal ISO镜像 Minimal ISO镜像,与DVD ISO镜像的差别有很多,这里只说两点 1.Minimal ISO类似于Windows的纯净…

[Objective-C语言教程]结构体(17)

Objective-C数组可定义包含多个相同类型的数据项的变量类型,但结构体是Objective-C编程中的另一个用户定义数据类型,它可组合不同类型的数据项。 结构体用于表示记录,假设要图书馆中跟踪书籍信息。可能希望跟踪每本书的以下属性 - 标题作者学…

Scala01入门

第1章 可伸展的语言 Scala应用范围广,从编写脚本,到建立大型系统。 运行在标准Java平台上,与Java库无缝交互。 更能发挥力量的地方:建立大型系统或可重用控件的架构。 将面向对象和函数式编程加入到静态类型语言。 在Scala中&a…

架构师之路17年精选80篇

【架构必备】 《互联网架构如何实现“高并发”》4W 《TCP接入层的负载均衡、高可用、扩展性架构设计》2.2W 《配置中心架构设计演进》1.7W 《跨公网调用的大坑与架构优化》1.4W 《DNS在架构设计中的巧用》1.9W 《消息如何在网络上安全传输》1.2W 《10W定时任务,如何…

iphone手机型号获取

#import <sys/utsname.h> //手机型号 NSString *device [self iphoneType]; (NSString *)iphoneType { struct utsname systemInfo; uname(&systemInfo); NSString *platform [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding]; if…

Java网络01基本网络概念

协议 Protocol&#xff1a;明确规则 &#xff08;1&#xff09;地址格式&#xff1b; &#xff08;2&#xff09;数据如何分包&#xff1b; ... TCP/IP四层模型&#xff1a; 应用层 HTTP SMTP POP IMAP 传输层 TCP UDP 网际层 IP 主机网络层 host to host layer 数模、…

apache的产品分类说明

分类 项目名 说明 开发语言 服务器&#xff08;共20&#xff09; Apache HTTP Server全球第一HTTP服务器C/CTomcatJava的Web服务器JavaJames邮件服务器JavaSpamAssassin反垃圾邮件C/CPerlApache的Perl编程语言支持C/CTclTCL脚本语言C/CDirectory Server超级目录服务器JavaAxisW…

Java网络02基本Web概念

URI Uniform Resource Identifier 同一资源标识符 以特定语法标识一个资源的字符串 绝对URI&#xff1a;URI模式模式特有部分 scheme:scheme-specific-part scheme分为&#xff1a; data file本地文件系统 ftp http telnet urn 统一资源名 scheme-specific-part为&am…

解决自建ca认证后浏览器警告

前一篇讲解了基本的建立证书的过程&#xff0c;但是建立后总是会在浏览器那里警告&#xff1a; 此链接不是私密链接 --谷歌浏览器 此证书颁发机构不可信 此证书不是这个网站的 --ie浏览器 总之证书是生成成功了&#xff0c;但是其中的内容填写错误了&a…

设计模式学习(三)——单例模式

在Java开发过程中&#xff0c;很多场景下都会碰到或要用到单例模式&#xff0c;在设计模式里也是经常作为指导学习的热门模式之一&#xff0c;相信每位开发童鞋都用到过。我们总是沿着前辈的足迹去做设定好的思路&#xff0c;往往没去探究为何这么做&#xff0c;所以这篇文章对…

Java网络03流

网络程序所做的很大一部分工作只是输入和输出&#xff1a;从一个系统向另一个系统移动数据。 输出流 Java的基本输出流类是java.io.OutputStream: public abstract class OutputStream 这个类提供了写入数据所需的基本方法&#xff0c;包括&#xff1a; public abstract vo…

基于微信小程序开发的仿微信demo

(本文参考自github/liujians,地址:https://github.com/liujians/weApp) 作者声明&#xff1a; 基于微信小程序开发的仿微信demo 整合了ionic的样式库和weui的样式库 使用请查看使用必读! 更新日志请点击这里 目前功能 查看消息 网络请求获取数据&#xff08;download示例server…

设计模式之六大原则

设计模式之设计原则 这软件设计过程中&#xff0c;有六大设计原则&#xff1a; 单一职责原则里氏替换原则依赖倒置原则接口隔离原则迪米特法则开闭原则由于软件开发过程中&#xff0c;根据业务不同等因素形成了各种复杂的而不可预料的需求&#xff0c;遵守原则&#xff0c;让项…

安装配置tengine

安装tengine 1、依赖gcc openssl-devel pcre-devel zlib-devel 安装&#xff1a;yum install gcc openssl-devel pcre-devel zlib-devel 2、解压tengine压缩包&#xff0c;并进入目录&#xff1b; 3、./configure --prefix/usr/tengine 4、make && make install 5…

使用springboot集成jseesite

请访问 开源中国下的https://git.oschina.net/wolfking/wolfking-jeesitehttps://www.oschina.net/p/wolfking-jeesite?fromerr6Iie3qZt 下载源码&#xff0c;按照如下的运行使用 springboot 改造 jeesite&#xff0c;只保留最简单的系统配置 。 介绍 1、运行主类&#xff0c;…

解决idea 中web项目无法正常显示的问题

转载于:https://www.cnblogs.com/nulijiushimeili/p/10575364.html