平衡二叉树定义:
1.任意结点的左右子树均为平衡二叉树
2.根结点左右子树的高度差绝对值小于等于1
平衡二叉树的插入,删除,查找时间复杂度均为0(logN)
平衡二叉树的失衡情况:
1.左左型失衡
处理 (向左旋)a.将其根结点的左子树作为新的根结点
b.原来根结点作为新根结点的右子树
c.如果新根结点原来有右子树,则作为旧根结点的左子树
2.右右型失衡
处理:(向右旋)a.将其根结点的右子树作为新的根结点
b.原来根结点作为新根结点的左子树
c.如果新根结点原来有左子树,则作为旧根结点的右子树
3.左右型失衡
处理: a.对根结点的左子树进行向右旋的操作
b.之后对根结点这个整树进行向左旋的操作
4.右左型失衡
处理: a.对根结点的右子树进行向左旋的操作
b.之后对根结点这个整数进行向右旋的操作
下面提供源代码以及测试函数,代码右边有注释
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
typedef struct node
{
int val;
struct node *left;
struct node *right;
int height;
node(int n):val(n),left(nullptr),right(nullptr),height(1){}
node():val(0),left(nullptr),right(nullptr),height(0){}
}TreeNode;
int GetHei(TreeNode *root)
{
if(root==nullptr) return 0;
int le=GetHei(root->left);
int ri=GetHei(root->right);
return (max(le,ri)+1);
}
TreeNode* LeftRotate(TreeNode *root) //向左旋 ,处理LL 型失衡
{
TreeNode* newroot=root->left; //将根结点的左子树作为新的根节点
root->left=newroot->right; //因此将原根结点作为新根结点的右子树
newroot->right=root; //如果新根结点原来有右子树,则作为原根节点的左子树
root->height=GetHei(root);
newroot->height =GetHei(newroot); //重新更新树高
return newroot;
}
TreeNode* RightRotate(TreeNode *root) //向右旋,处理RR 型失衡
{
TreeNode* newroot=root->right; //将根结点的右子树作为新的根结点
root->right=newroot->left; //原根结点作为新根结点的左子树
newroot->left=root; //如果新根结点原来有左子树,则作为原根结点的右子树
root->height=GetHei(root);
newroot->height=GetHei(newroot); //重新更新树高
return newroot;
}
TreeNode* LeftRightRotate(TreeNode* root) //先向左旋转再向右旋转,处理 RL 右左型失衡
{
root->right=LeftRotate(root->right); //先对根结点的右子树进行左旋,成为RR 型
root=RightRotate(root); //然后对整棵树进行右旋转
return root;
}
TreeNode* RightLeftRotate(TreeNode* root) //先向右旋转再向左旋转,处理LR 左右型失衡
{
root->left=RightRotate(root->left); //先对根结点的左子树进行向右旋转,成为LL 型
root=RightRotate(root); //然后对整棵树进行向左旋转
return root;
}
TreeNode* InsertNode(TreeNode* root,int key)
{
if(root==nullptr)
{
root=new TreeNode(key);
return root;
}
if(key <root->val ) //小于根结点,插入其左子树
{
root->left=InsertNode(root->left,key);
if((GetHei(root->left) -GetHei(root->right) )==2) //等于二代表不平衡,具体左左失衡 还是左右 失衡需要继续判断
{
if(key <root->left->val ) //插入值小于左子树的值,则为左左失衡
{
root=LeftRotate(root); //左左型
}
else //否则即为左右失衡
{
//左右型
root=RightLeftRotate(root);
}
}
}
else if(key> root->val)
{
root->right=InsertNode(root->right,key);
if((GetHei(root->left )-GetHei(root->right))==-2) //等于—2 表示不平衡
{
if(key >root->right->val) //右右型失衡
{
root=RightRotate(root);
}
else //右左型 失衡
{
root=LeftRightRotate(root);
}
}
}
root->height=GetHei(root); //重新更新树高
return root;
}
void layerbrowse( TreeNode *root) //层序遍历二叉树
{
if(root==nullptr)
return ;
queue<TreeNode*> que;
que.push(root);
while(!que.empty())
{
int size=que.size();
for(int i=0;i<size;i++)
{
TreeNode *temp=que.front();
que.pop();
cout<<temp->val<<" ";
if(temp->left !=nullptr) que.push(temp->left);
if(temp->right!=nullptr) que.push(temp->right);
}
}
}
void layerCreate(TreeNode *&root) //层序生成二叉树,层序生成二叉树测试案例
{ //30 15 41 0 0 33 50 0 35 45 52 34 0 0 0 0 0 0 0
queue<TreeNode*> que;
int jud;
cin>>jud;
if(jud!=0)
{
root=new TreeNode(jud);
que.push(root);
}
else return ;
while(!que.empty())
{
TreeNode *cur=que.front();
que.pop();
cin>>jud;
if(jud!=0)
{
TreeNode *temp=new TreeNode(jud);
que.push(temp);
cur->left=temp;
}
else cur->left=nullptr;
cin>>jud;
if(jud!=0)
{
TreeNode *temp=new TreeNode(jud);
que.push(temp);
cur->right=temp;
}
else cur->right=nullptr;
}
}
void perbrowse(TreeNode *root) //递归前序遍历
{
if(root==nullptr) return ;
cout<<root->val<<" ";
perbrowse(root->left);
perbrowse(root->right);
}
int main()
{
TreeNode *root=nullptr;
int n;
for(int i=0;i<9;i++) //输入九个结点
{
cin>>n;
root=InsertNode(root,n);
}
layerbrowse(root);
cout<<endl;
perbrowse(root); //通过层序遍历与前序遍历来画出这个二叉树,看其是否平衡
}