二叉树
是一种常用的数据结构,处理起来比普通树要简单、方便多,并且普通树容易转换成二叉树
定义:节点的度最多为2
特殊的二叉树:
满二叉树:每层的节点数都满足 2^(i-1) 个(i>=1 层数)
完全二叉树: 深度为k,有n个节点的二叉树当且仅当其每一个节点都与深度为k的满二叉树中编号从1到n的节点一一对应时,称为完全二叉树
除最后一层外,其它层全满,最后一层的节点必须从左到右依次排列,就称为完全二叉树
有序二叉树、排序二叉树、搜索二叉树、查找二叉树、平衡二叉树AVL树、堆(大顶堆、小顶堆)、红黑树、哈夫曼树、线索二叉树
二叉树的性质(重点):
性质1:二叉树的第i层上至多有2^(i-1)(i≥1)个节点
性质2:深度为h的二叉树中至多含有2^h-1个节点
性质3:若在任意一棵二叉树中,有n0个叶子节点,有n2个度为2的节点,则必有n0=n2+1
性质4:具有n个节点的满二叉树深为log2n+1
性质5:若对一棵有n个节点的完全二叉树进行顺序编号(1≤i≤n),那么,对于编号为i(i≥1)的节点:
当i=1时,该节点为根,它无双亲节点
当i>1时,该节点的双亲节点的编号为i/2
若2i≤n,则有编号为2i的左节点,否则没有左节点
若2i+1≤n,则有编号为2i+1的右节点,否则没有右节点
二叉树的操作:
构建、销毁、遍历、高度、密度、插入、删除、查询、求左、求右
二叉树的遍历(重点):
前序:根、左、右
中序:左、根、右
后序:左、右、根
层序:从上到下、从左到右的顺序依次遍历一棵树,必须配合队列完成
注意:前中后序遍历取决于根的遍历顺序,左右子树的遍历顺序不会改变
注意:可以根据 前序+中序 或者 后序+中序 就可以还原一棵树,但是只有一个遍历或者 前序+后序 是无法还原的
要会写遍历结果、能倒推还原树
一、有序二叉树
又称二叉排序树、二叉搜索树、二叉查找树
左子树的数据小于根的数据,根的数据要小于等于右子树的数据,这种树称为有序二叉树
有序二叉树中的中序遍历的结果是从小到大排序,因此有序二叉树也可以是一种排序算法
并且对有序二叉树的查找天然是二分查找,所以有序二叉树经常考
注意:需要会根据插入的数据,还原一棵有序二叉树
二、线索二叉树
规律:在有n个节点的链式二叉树中,必定存在n+1个空指针域
在链式二叉树中有很多没被使用的空指针,会造成一定的浪费
在有序二叉树中,可以让这些空指针指向下一个\前一个节点,这种树称为线索二叉树
在线索二叉树中,以中序遍历树时,可以不用递归而是通过循环即可,从而提高遍历树的效率、节约内存
中序线索二叉树节点数据项:
数据
左子树指针
右子树指针
右子树是否是线索标志(为真:右子树线索 为假:右子树不是线索)
实现线索二叉树的过程:
1、生成得到一颗普通的有序二叉树
2、按照中序遍历整棵树进行创建线索
3、按照线索循环遍历线索二叉树
三、选择树(胜者树、败者树)
是一种完全二叉树,把待比较的数据存储在最后一层,根节点是左右子树中的其中一个,是他们的最大或最小值,不停地比较形成一棵选择树
作用:能快速地找出最大值或最小值,如果带比较数据有部分更新,重新选择的速度也很快
四、堆 heap
是一种完全二叉树,不适合使用链式存储,适合用顺序存储
大顶堆(大根堆):
根节点比左右子树大
小顶堆(小根堆):
根节点比左右子树小
数据项:
存储数据的内存首地址
容量
数量
操作:
创建、添加、删除、空堆、满堆、堆顶
一、平衡二叉树
平衡二叉搜索树、AVL树
它是一棵有序二叉树,它的左右子树高度差不超过1,且它的所有子树都满足这个条件
如果有一个有序的二叉树接近单支状,它的查找效率很接近链表,因此只有当它达到平衡时它的查找效率是最高的
由于是有序二叉树,节点的位置是要受到值影响,所以只能通过调整节点关系来达到平衡状态
平衡二叉树不平衡的基础原因:
x y
/ \ / \
y t1 以y为轴向右选择 z x
/ \ / \ / \
z t2 t3 t4 t2 t1
/ \
t3 t4
x y
/ \ / \
t1 y 以y为轴向左选择 x z
/ \ / \ / \
t2 z t1 t2 t3 t4
/ \
t3 t4
x x z
/ \ / \ / \
y t1 z t1 y x
/ \ / \ / \ / \
t2 z y t4 t2 t3 t4 t1
/ \ / \
t3 t4 t2 t3
以z为轴左旋转 以z为轴右旋转
x x z
/ \ / \ / \
t1 y t1 z x y
/ \ / \ / \ / \
z t2 t3 y t1 t3 t4 t2
/ \ / \
t3 t4 t4 t2
以z为轴右旋转 以z为轴左旋转
注意:都是找中间值为轴 进行左旋右旋
二、红黑树
是一种自平衡的二叉树,但不是严格遵循高度差不超过1原则,是一种伪平衡的二叉树,是通过节点的高度以及节点的颜色来达到相对平衡的状态
红黑树的特征:
(1)每个节点或者是黑色,或者是红色。
(2)根节点是黑色。
(3)每个叶子节点(NIL)是黑色。 [注意:这里叶子节点,是指为空(NIL或NULL)的叶子节点!]
(4)如果一个节点是红色的,则它的子节点必须是黑色的。
(5)从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。
红黑树的优缺点:(为什么要选择红黑树?)
优点:插入、删除效率比AVL树要高,因为旋转调整的频率没有AVL树高
缺点:没有AVL树那么平均,查找效率没有AVL树那么高,但是也不差
红黑树的综合性能是最优的,很多的标准库的数据结构的底层实现是使用了红黑树
三、哈夫曼树\霍夫曼树
路径长度:从一个节点开始到另一个节点之间的路径条目数
根节点到第L层上的任意节点的路径长度L-1
树的路径长度:从根节点出发到每个节点的路径长度之和
节点的权:将树中的节点额外赋予某种含义的数值,该数值就称为节点的权
节点的带权路径长度:从根节点出发到该节点之间的路径长度与该节点权的乘积
树的带权路径长度:所有叶子节点的带权路径长度之和,简称WPL
WPL是衡量一棵带权二叉树优劣的关键
示例:
成绩 <60 60~69 70~79 80~89 90~100
评级 E D C B A
比例 5% 15% 40% 30% 10%
普通的带权二叉树的
WPL=10+30*2+40*3+15*4+5*4 = 270
经过优化后的带权二叉树的
WPL=40+30*2+15*3+10*4+5*4 = 205
哈夫曼树是一棵带权二叉树且它的WPL最小
构建一棵哈夫曼树:
1、把n个带权节点存入集合F中,每个节点左右子树置空
2、从F中选取根节点的权值最小的两个节点,作为左右子树构建成一棵新的二叉树,把左右子树的权值之和作为该树的根节点的权值
3、从F中删除刚刚选择的两个节点,把新得到的二叉树放入F中
4、重复第2、3步骤,直到F中只剩下一棵树,便是哈夫曼树
WPL=40+30*2+15*3+10*4+5*4 = 205
四、哈夫曼编码
目的:当年是为了解决远距离通信时传输数据的最优解问题
待发送文字:ABCAA EEDFB
方法1:转成二进制发送
A 000 B 001 C010 D011 E100 F101
总共要发送30个0\1
方法2:
1、根据待发送文字的频率,构建一棵哈夫曼树
假设频率:A27 B8 C15 D15 E30 F5
2、设置哈夫曼树的左分支为0、右分支为1,从根节点出发到每个叶子节点经过的路径分支组成的0\1的编码就是所谓的哈夫曼编码
A 01 B 1001 C 101 D 00 E 11 F 1000
011001101010111110010001001