想必大家一定会问有了二叉搜索树为啥还要平衡二叉树呢,大家是否想过这样的一个问题,假如我们向一颗二叉树中插入这些1,2,3,4,5,6,7数据这颗二叉树会变成什么呢?
答案很明确这颗二叉树虽然有着二叉树但是他视乎变成了一个链表,查找起来依然没有剩下时间,反而让开销更大,为了防止这种情况的产生,使其这颗二叉树依然高效,于是就有了平衡二叉树
什么是平衡二叉树:
基于二叉排序树左右子树的深度之差的绝对值不超过1左右子树都是平衡二叉树
那么在建立树的过程中,我们如何知道左右子树的高度差呢?在这里我们采用了平衡因子进行记录。
平衡因子:左子树的高度减去右子树的高度。由平衡二叉树的定义可知,平衡因子的取值只可能为0,1,-1.分别对应着左右子树等高,左子树比较高,右子树比较高。
我们使用一个结构体来保存我们每个节点所需的信息,这里多出了一个树的的高度因此我们需要比以往的二叉树结构体多出一个整形来存储高度:
//使用模板
template<typename T>
struct TreeNode {
int height;
T val;
TreeNode<T>* left;
TreeNode<T>* right;
TreeNode<T>(T val) :val(val), left(NULL), right(NULL) {
}
};
AVL树的插入时的失衡与调整:
在构造二叉排序树的过程中,会出现四种失衡现象
LL型
我们进行右旋转,我们以3 – 2为轴向右旋转 我们将 2的右节点赋值3节点,假如2的右节点不为空,。那么他一定大于2小于3 那么我们将3的左节点赋值为2的原来的右节点,那么本次不就循环完成。
RR型
同LL型
LR型:
对于这种情况我们先按照1 — 2 为轴向左旋转,旋转成右幅图这样,在按照LL型进行右旋转。
RL型:
实现代码:
#pragma once
#include"预编译.h"
template<typename T>
struct TreeNode {
int height;
T val;
TreeNode<T>* left;
TreeNode<T>* right;
TreeNode<T>(T val) :val(val), left(NULL), right(NULL) {
}
};
template<class T>
class BalancedBinaryTree
{
private:
TreeNode<T>* root;
queue<TreeNode<T>*> level;
public:
BalancedBinaryTree()
{
root = NULL;
}
BalancedBinaryTree(const BalancedBinaryTree& bbt)
{
if (bbt == this)
{
return;
}
root = bbt;
}
void insertBalanceBinaryTree(T val)
{
root = InsertBalanceBinaryTree(root, val);
}
TreeNode<T>* InsertBalanceBinaryTree(TreeNode<T>* root,T val)
{
if (root == NULL)
{
root = new TreeNode<T>(val);
root->height = 0;
}
//进行二叉树的查找
else if (root->val > val)
{
root->left = InsertBalanceBinaryTree(root->left, val);
if (getHeightTree(root->left) - getHeightTree(root->right) == 2)
{
if (val < root->left->val)
{
root = LLRotation(root);
}
else
{
root = LRRotation(root);
}
}
}
else
{
root->right = InsertBalanceBinaryTree(root->right, val);
if (getHeightTree(root->right) - getHeightTree(root->left) == 2)
{
if (val > root->right->val)
{
root = RRRotation(root);
}
else
{
root = RLRotation(root);
}
}
}
//更新根节点的平衡因子 也就是调整之后树的高度
root->height = max(getHeightTree(root->left), getHeightTree(root->right)) + 1;
std::cout << root->val << " "<< root->height << endl;
return root;
}
//获取树的高度 如果为空就是-1
int getHeightTree(TreeNode<T>* root)
{
if (root == NULL)
{
return -1;
}
return root->height;
}
// 10
// 8
// 7
//适用于LL型 进行右旋转
TreeNode<T>* LLRotation(TreeNode<T>* root)
{
std::cout << "进行右旋转" << endl;
TreeNode<T>* temp = NULL;
if (root != NULL)
{
TreeNode<T>* lc = root->left;
if (lc->left != NULL)
{
root->left = lc->right;
lc->right = root;
}
lc->height = max(getHeightTree(lc->left), getHeightTree(lc->right)) + 1;
root->height = max(getHeightTree(root->left), getHeightTree(root->right)) + 1;
temp = lc;
}
return temp;
}
// 8
// 9
// 10
//进行左旋转 对于RR型的数据
TreeNode<T>* RRRotation(TreeNode<T>* root)
{
std::cout << "进行左旋转" << endl;
TreeNode<T>* temp = NULL;
if (root != NULL)
{
TreeNode<T>* rc = root->right;
root->right = rc->left;
rc->left = root;
rc->height = max(getHeightTree(rc->right), getHeightTree(rc->left)) + 1;
root->height = max(getHeightTree(root->left), getHeightTree(root->right)) + 1;
temp = rc;
}
return temp;
}
//进行右左旋 先进行右旋在进行左旋 对应的是RL型
// 8
// 6
//
// 7
//进行左右旋转 先进行左旋在进行右旋
TreeNode<T>* LRRotation(TreeNode<T>* root)
{
std::cout << "进行左右旋转" << endl;
if (root != NULL)
{
root->left = RRRotation(root->left);
root = LLRotation(root);
}
return root;
}
//进行右左旋 先进行右旋在进行左旋 对应的是RL型
// 5
// 8
//
// 6
TreeNode<T>* RLRotation(TreeNode<T>* root)
{
std::cout << "进行右左旋转" << endl;
if (root != NULL)
{
root->right = LLRotation(root->right);
root = RRRotation(root);
}
return root;
}
//平衡二叉树的前序遍历
void PreorderTraversal()
{
preorderTraversal(root);
}
//平衡二叉树的层序遍历
void LevelTraversal()
{
if (!IsEmpty())
{
return;
}
level.push(root);
while (!level.empty())
{
TreeNode<T>* temp = level.front();
level.pop();
std::cout << "值为:" << temp->val << "高度为:" << temp->height << " ";
if (temp->left != NULL)
{
level.push(temp->left);
}
if (temp->right != NULL)
{
level.push(temp->right);
}
}
}
void DeleteBalanceTree(T val)
{
if (root == NULL)
{
return;
}
root = deleteBalanceTree(root, val);
}
//判断平衡二叉树是否为空
bool IsEmpty()
{
if (root == NULL)
{
return false;
}
return true;
}
bool Find()
{
return findTreeNode(root);
}
private:
TreeNode<T>* deleteBalanceTree(TreeNode<T>* root, T val)
{
if (root == NULL)
{
return NULL;
}
if (root->val == val)
{
return deleteTreeNode(root);
}
else if (root->val > val)
{
root->left = deleteBalanceTree(root->left, val);
if (getHeightTree(root->left) - getHeightTree(root->right) == 2)
{
if (val < root->left->val)
{
root = LLRotation(root);
}
else
{
root = LRRotation(root);
}
}
}
else
{
root->right = deleteBalanceTree(root->right, val);
if (getHeightTree(root->left) - getHeightTree(root->right) == -2)
{
if (val < root->left->val)
{
root = RRRotation(root);
}
else
{
root = RLRotation(root);
}
}
}
root->height = max(getHeightTree(root->left), getHeightTree(root->right)) + 1;
return root;
}
TreeNode<T>* deleteTreeNode(TreeNode<T>* root)
{
TreeNode<T>* tmp, * smp;
if (root->left == NULL && root->right == NULL)
{
tmp = root;
root = root->left;
delete(tmp);
}
else if (root->left != NULL && root->right == NULL)
{
tmp = root;
root = root->left;
delete(tmp);
}
else if (root->left == NULL && root->right != NULL)
{
tmp = root;
root = root->right;
delete(tmp);
}
else
{
tmp = root;
smp = tmp->left;
while (!smp->right)
{
tmp = smp;
smp = smp->right;
}
root->val = smp->val;
if (root != tmp)
{
tmp->right = smp->left;
}
else
{
tmp->left = smp->right;
}
delete(smp);
}
return root;
}
bool findTreeNode(TreeNode<T>* root, const T& val)
{
if (root == NULL)
{
return false;
}
if (root->val == val)
{
return true;
}
else if (root->val > val)
{
findTreeNode(root->left, val);
}
else
{
findTreeNode(root->right, val);
}
}
//前序遍历的内部操作函数不可见
void preorderTraversal(TreeNode<T>* root)
{
if (root == NULL)
{
return;
}
std::cout << "值为:" << root->val << "高度为:" << root->height << endl;
preorderTraversal(root->left);
preorderTraversal(root->right);
}
};
测试程序:
void test_06()
{
BalancedBinaryTree<int>* root = new BalancedBinaryTree<int>();
root->insertBalanceBinaryTree(50);
root->insertBalanceBinaryTree(45);
root->insertBalanceBinaryTree(40);
root->PreorderTraversal();
root->LevelTraversal();
std::cout << endl;
std::cout << "--------------------------------------------"<<endl;
BalancedBinaryTree<int>* root1 = new BalancedBinaryTree<int>();
root1->insertBalanceBinaryTree(40);
root1->insertBalanceBinaryTree(45);
root1->insertBalanceBinaryTree(50);
root1->PreorderTraversal();
root1->LevelTraversal();
std::cout << endl;
std::cout << "--------------------------------------------" << endl;
BalancedBinaryTree<int>* root2 = new BalancedBinaryTree<int>();
root2->insertBalanceBinaryTree(40);
root2->insertBalanceBinaryTree(50);
root2->insertBalanceBinaryTree(45);
root2->PreorderTraversal();
root2->LevelTraversal();
std::cout << endl;
std::cout << "--------------------------------------------" << endl;
BalancedBinaryTree<int>* root3 = new BalancedBinaryTree<int>();
root3->insertBalanceBinaryTree(50);
root3->insertBalanceBinaryTree(40);
root3->insertBalanceBinaryTree(45);
root->insertBalanceBinaryTree(60);
root3->PreorderTraversal();
root3->LevelTraversal();
}
int main()
{
test_06();
return 0;
}