【知识点】平衡二叉树(AVL树)

平衡二叉树的概念

根结点左子树高度-右子树高度为平衡因子(BF)。
所有子树平衡因子绝对值小于等于1的的查找二叉树称为平衡二叉树
插入后需要使用旋转进行纠正。
距离插入节点最近的,并且平衡因子的绝对值大于1的节点为根节点的子树称为最小不平衡子树
只需要对最小不平衡子树进行旋转纠正即可。

旋转纠正

两种旋转方式

  1. 左旋
  • 旧根结点作为新根节点的左子树
  • 新根节点的原左子树作为旧根结点的右子树
  1. 右旋
  • 旧根结点作为新根节点的右子树
  • 新根节点的原右子树作为旧根结点的左子树

四种纠正类型

  1. LL型:右旋
  2. RR型:左旋
  3. LR型:先左旋后右旋
  4. RL型:先右旋后左旋

完整代码

#include <iostream>
#include <algorithm>
using namespace std;

typedef struct TreeNode{
	//数据域
	int data;
	//指针域
	TreeNode *LChild,*RChild;
	//属性
	int height;
	//构造器
	TreeNode(int a){
		LChild = RChild = NULL;
		height = 0;
		this->data = a;
	}
}*Node;

//返回新根结点的四种纠正
Node LLRotate(Node root){
	Node temp = root->LChild;
	root->LChild = temp->RChild;
	temp->RChild = root;
	return temp;
}

Node RRRotate(Node root){
	Node temp = root->RChild;
	root->RChild = temp->LChild;
	temp->LChild = root;
	return temp;
}

Node LRRotate(Node root){
	root->LChild = RRRotate(root->LChild);
	return LLRotate(root);
}

Node RLRotate(Node root){
	root->RChild = LLRotate(root->RChild);
	return RRRotate(root);
}

//递归求树高
int heit(Node root){
	if(root == NULL)
		return 0;
	return max(heit(root->LChild)+1, heit(root->RChild)+1);
}

//求该节点平衡因子
int BF(Node now){
	return heit(now->LChild) - heit(now->RChild);
}

//平衡函数
Node Balance(Node root){
	int fact = BF(root);
	if(fact > 1){
		if(BF(root->LChild) > 0)	//LL的情况
			root = LLRotate(root);
		else	//LR的情况
			root = LRRotate(root);
	}
	else if(fact < -1){
		if(BF(root->RChild) < 0)	//RR的情况
			root = RRRotate(root);
		else	//RL的情况
			root = RLRotate(root);
	}
	return root;
}

//插入节点
Node Insert(Node now,int a){
	if(now == NULL){
		now = new TreeNode(a);
		return now;
	}
	if(a == now->data)
		return now;
	//递归
	if(a < now->data)
		now->LChild = Insert(now->LChild,a);
	else
		now->RChild = Insert(now->RChild,a);
	now = Balance(now);	//平衡路径上的每个节点
	return now;
}

//中序遍历打印二叉树
void print(Node now){
	if(now == NULL)
		return;
	print(now->LChild);
	printf("%d ",now->data);
	print(now->RChild);
	return;
}

//直观简单打印二叉树
void printTree(Node n)
{
	static int level = -1; //记录是第几层次
	int i;
	if (NULL == n)
		return;
	level++;
	printTree(n->RChild);
	for (i = 0; i < level; i++)
		printf("\t");
	printf("%2d\n", n->data);
	printTree(n->LChild);
	level--;
}


int main(){
	//在主函数中测试
	int array[10] = {4,5,6,3,2,8,7,9,0,1};
	//构造平衡二叉树
	Node root = NULL;
	for(int i = 0;i<10;i++)
	{
		root = Insert(root,array[i]);
		printf("\n\n\n");
		printTree(root);
	}
	print(root);
	return 0;
}

测试输出结果为




 4



         5
 4



         6
 5
         4



         6
 5
         4
                 3



         6
 5
                 4
         3
                 2



                 8
         6
 5
                 4
         3
                 2



                 8
         7
                 6
 5
                 4
         3
                 2



                         9
                 8
         7
                 6
 5
                 4
         3
                 2



                         9
                 8
         7
                 6
 5
                 4
         3
                 2
                         0



                         9
                 8
         7
                 6
 5
                 4
         3
                         2
                 1
                         0
0 1 2 3 4 5 6 7 8 9

其中,添加6时RR调整,添加2时LL调整,添加7时RL调整,添加1时LR调整,可以自行感受。

posted @ 2025-01-15 15:18  Alkaid16  阅读(49)  评论(0)    收藏  举报