二叉排序树
二叉排序树又称“二叉查找树”、“二叉搜索树”(简称\(BST\))。二叉排序树:或者是一棵空树,或者是具有下列性质的二叉树:
- 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
- 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
- 它的左、右子树也分别为二叉排序树。 
从BST性质可推出:按中序遍历该树所得到的中序序列是一个递增的有序序列
- 构造\(BST:\) 
- 查找 
删除:删除一个节点不能把以该节点为根的子树都删除,只能删除这个节点并保持二叉树排序树的特性。即相当于删除有序序列中的一个记录,只要在删除某结点之后调整树中某些结点,使之继续保持二叉排序树的特性即可。主要分为以下四种情况:
- 叶子节点:由于没有左右子树,因此直接删除不会破坏原有二叉树的结构
- 左单分支节点:只须将\(*p\)节点的左子树直接作为双亲节点\(*f\)的左孩子即可
- 右单分支节点:只须将\(*p\)节点的右子树直接作为双亲节点\(*f\)的右孩子即可
双分支节点: 若\(*p\)节点的左、右子树不空。分为两种方法:
- 用\(*p\)节点的左子树的最右下节点(对应左子树的最右节点)\(*r\)的值代替\(*p\)节点的值,然后用第\(2\)种和第\(3\)种情况删除\(*r\)节点
- 用\(*p\)节点的右子树的最左下节点(对应右子树的最左节点)\(*r\)的值代替\(*p\)节点的值,然后用第\(2\)种和第\(3\)种情况删除\(*r\)节点
有一棵二叉排序树按先序遍历得到的序列为:\((50,38,30,45,40,48,70,75,80)\)。\((1)\)画出该二叉排序树 \((2)\)求在等概率下查找成功和不成功的平均查找长度(比较次数)

一棵\(BST\)的结构如图所示,其中各节点的关键字依次为\(32-40\)请标出各关键字。

根据中序遍历的结果可知:

判断一棵二叉树是否为二叉排序树


等概率下构造最佳二叉排序树的步骤
- 先将字典元素的关键码排序;
- 对每个关键码按二分法在排序关键码序列中执行检索, 将检索中遇到的还未在二叉排序树中的关键码插入二叉排序树中 
哈夫曼树
哈夫曼树是指在\(n\)个带权叶子节点构成的二叉树中,其中带权路径长度\(WPL\)最小的二叉树,也称为最优二叉树。「哈夫曼树没有度为1的节点」

构建哈夫曼树的方法
- 将所有左,右子树都为空的节点作为根节点,构建初始森林。
- 在森林中选出两棵根节点的权值最小的树作为一棵新树的左,右子树,且置新树的附加根节点的权值为其左,右子树上根节点的权值之和。注意,左子树的权值应小于右子树的权值。
- 从森林中删除这两棵树,同时把新树加入到森林中。
- 重复\(2,3\)步骤,直到森林中只有一棵树为止,此树便是哈夫曼树。 
哈夫曼编码:利用哈夫曼树求得的用于通信的二进制编码称为哈夫曼编码。树中从根到每个叶子节点都有一条路径,对路径上的各分支约定指向左子树的分支表示”0”码,指向右子树的分支表示“1”码,取每条路径上的“0”或“1”的序列作为各个叶子节点对应的字符编码,即是哈夫曼编码。
- 译码的唯一性:要求任一字符的编码都不能是另一字符编码的前缀「任意一个叶子结点都不可能在其它叶子结点的路径中」
- 数据的最小冗余编码问题:哈夫曼树的定义 

若度为\(m\)的哈夫曼树中,叶子节点个数为\(n\),则非叶子节点的个数为
\(\ulcorner \frac{(n-1)}{m-1} \urcorner\)
度为m的哈夫曼树,只包含有度为\(0\)的结点和度为\(m\)的结点,可以设度为\(m\)的结点个数为\(x\),则哈夫曼树中边的条数为\(mx\),
而树中边的条数为总结点数减\(1\),即\(n+x-1\),两式相等,可得\(x\)的值
假设二叉树采用二叉链存储结构,设计一个算法,求二叉树\(b\)中距离给定节点 \(*p\)最近的叶子节点。

假设一棵二叉树采用二叉链存储结构,设计一个算法,求非空二叉树中指定的某一层 \(k (k>1)\)的叶子节点的个数。


假设一棵二叉树采用二叉链存储结构,设计一个算法,输出从每个叶子节点到根节点逆路径(即根节点到某叶子节点的路径的逆序)
- 方式一:使用层次遍历,定义一种数据结构记录每个节点的父节点  
- 方式二:使用后根遍历  
- 使用递归方式:采用 \(path\) 数组存放路径, \(pathlen\)整数存放路径长度。