平衡二叉树(ALV树)

一、AVL树简介

  AVL树的名字来源于它的发明作者G.M. Adelson-Velsky 和 E.M. Landis。AVL树是最先发明的自平衡二叉查找树(Self-Balancing Binary Search Tree,简称平衡二叉树)。

  平衡二叉树定义(AVL):它或者是一颗空树,或者具有以下性质的二叉排序树:它的左子树和右子树的深度之差(平衡因子)的绝对值不超过1,且它的左子树和右子树都是一颗平衡二叉树。

  平衡因子:将二叉树上某个节点的左子树高度减去右子树高度的值称为该节点的平衡因子BF(Balance Factor)。

  二叉排序树基本概念

二、ALV树的平衡调整

定义结构体:

typedef struct Node
{
	int key;
	struct Node* left;
	struct Node* right;
	int height;
}BTNode;

1 获取平衡因子

//节点的高度
int height(BTNode* N){
	if (N == NULL)
		return 0;
	return N->height;
}

int getBF(BTNode* N){
	if (N == NULL)
		return 0;
	return height(N->left) - height(N->right);
}

2 对不平衡子树进行调整
1)LL型
此时节点1不平衡(BF = 2-0 = 2 > 1)

把节点1作为实参,进行旋转,代码如下

BTNode* ll_rotate(BTNode* y){
	BTNode* x = y->left;
	y->left = x->right;
	x->right = y;

	y->height = max(height(y->left), height(y->right)) + 1;
	x->height = max(height(x->left), height(x->right)) + 1;

	return x;
}

2)RR型
此时节点-1不平衡(BF = 0-2 = -2 < -1)
在这里插入图片描述
把节点-1作为实参,进行旋转,代码如下

BTNode* rr_rotate(BTNode* y){
	BTNode* x = y->right;
	y->right = x->left;
	x->left = y;

	y->height = max(height(y->left), height(y->right)) + 1;
	x->height = max(height(x->left), height(x->right)) + 1;

	return x;
}

3)LR型
1的平衡因子 BF = 2-0 =2 > 1
先将1的左子树进行RR型旋转,再对1进行LL型旋转
在这里插入图片描述
4)RL型
1的平衡因子 BF = 0-2 =-2 < -1
先将1的右子树进行LL型旋转,再对1进行RR型旋转
在这里插入图片描述

三、删除节点操作

先删除节点,再进行平衡调整

//删除
BTNode* delNode(BTNode* root, int key){

	if (root == NULL)
		return root;

	if (key < root->key)
		root->left = delNode(root->left, key);

	else if (key > root->key)
		root->right = delNode(root->right, key);

	else {
		if ((root->left == NULL) || (root->right == NULL)) {
			BTNode* temp = root->left ? root->left : root->right;

			if (temp == NULL) {
				temp = root;
				root = NULL;
			}
			else
				*root = *temp;
			free(temp);
		}
		else {
			BTNode* temp = minValueNode(root->right);
			root->key = temp->key;
			root->right = delNode(root->right, temp->key);
		}
	}
	if (root == NULL)
		return root;

	root->height = max(height(root->left), height(root->right)) + 1;
	//平衡调整
	root = isBanlance(root);
	return root;
}

四、附上完整代码

#include<stdio.h>
#include<stdlib.h>

typedef struct Node
{
	int key;
	struct Node* left;
	struct Node* right;
	int height;
}BTNode;

int height(BTNode* N){
	if (N == NULL)
		return 0;
	return N->height;
}

int max(int a, int b){
	return (a > b) ? a : b;
}

BTNode* newNode(int key){
	struct Node* node = (BTNode*)malloc(sizeof(struct Node));
	node->key = key;
	node->left = NULL;
	node->right = NULL;
	node->height = 1;
	return node;
}

BTNode* ll_rotate(BTNode* y){
	BTNode* x = y->left;
	y->left = x->right;
	x->right = y;

	y->height = max(height(y->left), height(y->right)) + 1;
	x->height = max(height(x->left), height(x->right)) + 1;

	return x;
}

BTNode* rr_rotate(BTNode* y){
	BTNode* x = y->right;
	y->right = x->left;
	x->left = y;

	y->height = max(height(y->left), height(y->right)) + 1;
	x->height = max(height(x->left), height(x->right)) + 1;

	return x;
}

int getBF(BTNode* N){
	if (N == NULL)
		return 0;
	return height(N->left) - height(N->right);
}

BTNode* isBanlance(BTNode* root) {
	int balance = getBF(root);
	//printf("key:%d H:%d B:%d\n",root->key,root->height,balance);
	if (balance > 1 && getBF(root->left) >= 0) //LL型
		return ll_rotate(root);
	if (balance < -1 && getBF(root->right) <= 0) //RR型
		return rr_rotate(root);

	//LR型
	if (balance > 1 && getBF(root->left) < 0) {
		root->left = rr_rotate(root->left);
		return ll_rotate(root);
	}
	//RL型
	if (balance < -1 && getBF(root->right) > 0) {
		root->right = ll_rotate(root->right);
		return rr_rotate(root);
	}
	return root;
}

BTNode* insert(BTNode* node, int key){
	if (node == NULL)
		return newNode(key);

	if (key < node->key)
		node->left = insert(node->left, key);
	else if (key > node->key)
		node->right = insert(node->right, key);
	else
		return node;

	node->height = 1 + max(height(node->left), height(node->right));
	node = isBanlance(node);
	return node;
}
BTNode* minValueNode(BTNode* node) {
	while (node->left != NULL) {
		node = node->left;
	}
	return node;
}
BTNode* maxValueNode(BTNode* node) {
	while (node->right != NULL) {
		node = node->right;
	}
	return node;
}
BTNode* delNode(BTNode* root, int key){

	if (root == NULL)
		return root;

	if (key < root->key)
		root->left = delNode(root->left, key);

	else if (key > root->key)
		root->right = delNode(root->right, key);

	else {
		if ((root->left == NULL) || (root->right == NULL)) {
			BTNode* temp = root->left ? root->left : root->right;

			if (temp == NULL) {
				temp = root;
				root = NULL;
			}
			else
				*root = *temp;
			free(temp);
		}
		else {
			BTNode* temp = minValueNode(root->right);
			root->key = temp->key;
			root->right = delNode(root->right, temp->key);
		}
	}
	if (root == NULL)
		return root;

	root->height = max(height(root->left), height(root->right)) + 1;
	root = isBanlance(root);
	return root;
}

void inOrder(BTNode* root){
	if (root != NULL) {
		inOrder(root->left);
		printf("%d ", root->key);
		inOrder(root->right);
	}
}

int main()
{
	BTNode* root = NULL;
	root = insert(root, 7);
	root = insert(root, 5);
	root = insert(root, 10);
	root = insert(root, 0);
	root = insert(root, 6);
	root = insert(root, 11);
	root = insert(root, -1);
	root = insert(root, 1);
	root = insert(root, 2);
	printf("中序遍历:\n");
	inOrder(root);
	/* 
					 7
					/  \
				   1    10
				 /  \     \
				0    5     11
			   /    /  \
			  -1   2    6
	*/
	puts("\ndel:");
	root = delNode(root, 10);
	/* del 10
					   1
					 /   \
					0     7
				  /     /  \
				-1     5     11
					 /  \
					2    6
	*/
	inOrder(root);
	return 0;
}


  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
判断一棵二叉是否为平衡二叉树可以采用递归的方式。对于每个节点,我们可以计算其左右子的高度差,如果高度差大于1,则该二叉不是平衡二叉树,否则递归判断其左右子是否是平衡二叉树。在递归时,可以同时判断该二叉是否为二叉排序,即左子的所有节点值都小于当前节点的值,右子的所有节点值都大于当前节点的值。 下面是递归判断平衡二叉树排序的代码实现: ```python class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right class Solution: def isBalanced(self, root: TreeNode) -> bool: if not root: return True left_height = self.get_height(root.left) right_height = self.get_height(root.right) if abs(left_height - right_height) > 1: return False return self.isBalanced(root.left) and self.isBalanced(root.right) and self.isBST(root.left, float('-inf'), root.val) and self.isBST(root.right, root.val, float('inf')) def get_height(self, node: TreeNode) -> int: if not node: return 0 return max(self.get_height(node.left), self.get_height(node.right)) + 1 def isBST(self, node: TreeNode, min_val: float, max_val: float) -> bool: if not node: return True if node.val <= min_val or node.val >= max_val: return False return self.isBST(node.left, min_val, node.val) and self.isBST(node.right, node.val, max_val) ``` 其中,`get_height`函数用于计算二叉的高度,`isBST`函数用于判断是否为二叉排序。`isBalanced`函数是递归判断平衡二叉树的主函数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小木荣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值