平衡二叉树

平衡二叉树定义

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);             //通过层序遍历与前序遍历来画出这个二叉树,看其是否平衡 
	
	
	
}












  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值