PAT 甲级 1066 Root of AVL Tree (25 分)平衡二叉树的创建
题目
这题主要考查了平衡二叉树的创建。除此之外还得一直保留二叉树的根节点。
由于此前对于平衡二叉树的创建比较模糊,故结合了严奶奶的教材写一篇博客加深一下自己对于平衡二叉树的创建的印象。
平衡二叉树概念
平衡二叉树是一种二叉排序树,将其不断调整为平衡二叉树是为了提高查找的效率。平衡二叉树的递归定义条件是:
- 对于根节点,其左子树和右子树的高度之差不得超过2,也即只能为0,1 。
- 这棵树的左子树和右子树也是平衡二叉树。
为什么说平衡二叉树可以提高查找效率?
现在我们来创建一颗普通的二叉排序树。输入序列为1,2,3,4,5。
![](https://raw.githubusercontent.com/Balala1/BlogPicture/master/img/20190730130022.png)
可以看见上述的二叉排序树的查找复杂度依旧为 O ( n ) O(n) O(n),故此种情况下排序树并没有提高查找效率。平衡二叉树的出现就是为了避免这种情况的发生。它通过调整使得最后的树左右子树高度相差不超过2 。从而让查找复杂度始终为 O ( l o g 2 n ) O(log_2n) O(log2n)。
平衡二叉树的创建
平衡二叉树的创建难在调整二叉树这个步骤上。而什么时候需要调整呢?有四种需要调整的情况。(下列图中节点上的数字并非该节点的value值,仅指编号,区分节点)
-
LL型
这里的LL中的L指的是Left。也即表示原本该树的左子树就比右子树高1。 这时新插入的节点还插入到了该左子树的左子树上。这时需要以1节点进行右旋。
这样就让二叉树平衡了。
-
LR型
这里指的是原本该树的左子树就比右子树高1,这时新插入的节点插入到了该左子树的右子树上。这时复杂一点,需要先以2节点进行左旋,再以1节点进行右旋。
从图中可以看出,先以2节点进行左旋是为了达到LL型的树,再以1节点进行右旋以达到平衡
-
RR型
这里指原本该树的右子树就比左子树高1 。这时新插入的节点插入到了改右子树的右子树上,这时只需要以1节点进行左旋即可达到平衡。
-
RL型
这里指的是原本该树的右子树就比左子树高1。 这时新插入的节点插入到了改右子树的左子树上,这时需要先以2节点进行右旋,再以1节点进行左旋。
![](https://raw.githubusercontent.com/Balala1/BlogPicture/master/img/20190730134028.png)
从图中可以看出,先以2节点进行右旋是为了达到RR型树,在进行左旋。
知道了上述的调整方法之后再利用递归函数便可完成平衡二叉树建立的代码。
我们知道,平衡二叉树需要调节平衡,那么必须知道各个节点处的平衡因子,所以平衡二叉树的节点会多一个元素即平衡因子。左右等高时为0 ;左高为1 ;右高为-1 。
完整代码
#include <iostream>
#include <cstdio>
#include <string>
#include <algorithm>
#include <map>
#include <queue>
#define LH +1 //左高
#define EH 0 //等高
#define RH -1 //右高
using namespace std;
typedef struct BSTree {
int val;
BSTree *left, *right;
int balance;//平衡因子
}BSTree, *TreeNode;