树(下)
1 二叉搜素树(BST)
查找分为静态查找和动态查找
静态查找中的二分法有很好的效果是因为事先对数据进行了有序的组织, 进而得到了类似于二叉判定树的结构
基于此, 是否可以让数据存储的时候直接使用这样的树形结构呢, 这就是二叉搜索树
二叉搜素树: 空二叉树或者满足一下条件的非空二叉树
1) 非空左子树的所有键值小于其根节点的键值
2) 非空右子树的所有键值大于其根节点的键值
3) 左右都是二叉搜索树
常用的功能:
1) 给定值查找该值在树中的地址: Find()
2) 查找最小元素的地址: FindMIn()
3) 查找最大元素的地址: FindMax()
4) 插入元素: Insert()
5) 删除元素: Delete()
1.1 查找
1) 基本查找
基本思想: 先与根节点值比较, 大于就转而比较右子树, 小于就比较左子树
该函数是一个递归函数, 效率不高
由于是尾递归, 可以将其改为迭代函数
2) 最大最小值查找
由于BST的特性, 最小值一定是在树的最左边, 最大值一定是在树的最右边
递归方式实现:
迭代方式实现:
1.2 插入
基本思路:
从根开始比较, 如果大就往根的右子树走, 如果小就往左子树走;
继续这样的判断, 直到往下走的时候, 该左子树或者右子树不存在, 那么这个子树的位置就是插入的位置
实现注意的地方:
要插入的时候, 需要知道该父节点(插入节点的)的位置, 因此往下走一层的时候, 需要记录一下当前节点
此处巧妙的利用递归, 查询子树的同时, 记录一个返回值, 这个返回值赋给它父节点的左右子树
保证非空时返回自己, 空时插入数据
既满足了插入数据, 也完好保留原BST
1.3 删除
删除分为三种情况
1) 删除的节点是叶节点
直接删除: 父节点指针域设置为null
2) 删除的节点有一个孩子结点
将父节点的指针指向孩子结点
3) 删除的节点有两个孩子结点
用右边最大的元素或者左边最小的元素替换
具体实现
2 平衡二叉树
BST的存在方便了排序, 但是同样的序列, 不同的排序顺序, 得到的BST是可能出现多种的
极端的说, 如果序列从小到大排序, 那么得到的BST将是一个只有右子树的二叉树, 这样显然是不合理的
因此针对这个"不合理", 有一个衡量指标, 平均查找长度ASL
ASL= (深度*该深度的结点数 累加)/总结点数
可以分析得到, BST如果左右子树分布的相对平衡, 得到的ASL应该是较小的
平衡因子(BF), 就是用来衡量平衡的
BF=HL - Hr
BF为左子树高度减去右子树高度
平衡二叉树(Balanced Binary Tree)(AVL树): 空树 或者 任意节点的左右树高度不超过1
3 堆
4 哈夫曼树和哈夫曼编码
5 集合及运算