C++数据结构--AVL树

一.什么是AVL树

AVL树,也叫二叉平衡搜索树,就是在BST树的基础上加了平衡操作(平衡的定义是任意节点的左右子树的高度差不超过1)。

其基本框架与BST树相同,不过为了保证其平衡,添加了节点的旋转操作:

cpp 复制代码
template<typename T>
class AVLTree
{
public:
	AVLTree()
		:root(nullptr)
	{ }
	~AVLTree(){}

private:
	struct Node
	{
		Node(T data=T())
			:m_data(data)
			,left(nullptr)
			,right(nullptr)
			,height(1)
		{ }
		


		T m_data;
		Node* left;
		Node* right;
		int height;//节点高度,用于旋转操作
	};
	Node* root;
};
//获取节点高度
int getHeight(Node* node)
{
	return node == nullptr ? 0 : node->height;
}

二.常见操作实现

1.平衡操作

(1).右旋转操作

如果添加一个元素后,左孩子的左子树太高了,那么需要进行右旋转,如图:。

这里的节点node与节点child的孩子节点都发生了变化,它们的高度需要进行更新。

cpp 复制代码
//右旋转操作
Node* rightRotate(Node* node)
{
	Node* child = node->left;
	node->left = child->right;
	child->right = node;

	node->height = max(getHeight(node->left), getHeight(node->right)) + 1;
	child->height = max(getHeight(child->left), getHeight(child->right)) + 1;
	return child;

}

(2).左旋转操作

如果添加一个元素后,右孩子的右子树太高了,那么需要进行左旋转,如图:

这里的节点node与节点child的孩子节点都发生了变化,它们的高度需要进行更新。

cpp 复制代码
//左旋转操作
Node* leftRotate(Node* node)
{
	Node* child = node->right;
	node->right = child->left;
	child->left = node;

	node->height = max(getHeight(node->left), getHeight(node->right)) + 1;
	child->height = max(getHeight(child->left), getHeight(child->right)) + 1;
	return child;

}

(3)左平衡操作

如果添加一个元素后,左孩子的右子树太高了,那么需要进行左平衡,如图:

cpp 复制代码
//左平衡操作(左-右)
Node* leftBalance(Node* node)
{
	node->left= leftRotate(node->left);
	return rightRotate(node);


}

(4)右平衡操作

如果添加一个元素后,右孩子的左子树太高了,那么需要进行右平衡,如图:

cpp 复制代码
//右平衡操作(右-左)
Node* rightBalance(Node* node)
{
	node->right= rightRotate(node->right);

	 return leftRotate(node);


}

2.插入操作

cpp 复制代码
Node* insert(const T& val,Node* node)
{
	if (node == nullptr)
	{
		return new Node(val);

	}
	if (node->m_data == val)
	{
		return node;
	}
	else if (node->m_data > val)
	{
		node->left = insert(val, node->left);
		if ((getHeight(node->left) - getHeight(node->right))>1)
		{
			if (getHeight(node->left->left) >= getHeight(node->left->right))
			{
				node = rightRotate(node);
			}
			else 
			{
				node = rightBalance(node);
			}
		}
		

	}
	else
	{
		node->right = insert(val, node->right);
		if ((getHeight(node->right) - getHeight(node->left)) > 1)
		{
			if (getHeight(node->right->right) >= getHeight(node->right->left))
			{
				node = leftRotate(node);
			}
			else
			{
				node = leftBalance(node);
			}
		}
	}
	node->height = max(getHeight(node->left), getHeight(node->right)) + 1;


	return node;
}

3.删除操作

cpp 复制代码
Node* remove(const T& val, Node* node)
{
	if (node == nullptr)
	{
		return nullptr;
	}
	if (node->m_data > val)
	{
		node->left = remove(val, node->left);
		if ((getHeight(node->right) - getHeight(node->left)) > 1)
		{
			if (getHeight(node->right->right) >= getHeight(node->right->left))
			{
				node = leftRotate(node);
			}
			else
			{
				node = leftBalance(node);
			}
		}
		
	}
	else if(node->m_data < val)
	{
		node->right = remove(val, node->right);
		if ((getHeight(node->left) - getHeight(node->right)) > 1)
		{
			if (getHeight(node->left->left) >= getHeight(node->left->right))
			{
				node = rightRotate(node);
			}
			else
			{
				node = rightBalance(node);
			}
		}
	}
	else
	{
		if (node->left != nullptr && node->right != nullptr)
		{
			if (getHeight(node->left) >= getHeight(node->right))
			{
				Node* pre = node->left;
				while (pre->right != nullptr)
				{
					pre = pre->right;
				}
				node->m_data = pre->m_data;
				
				node->left = remove( pre->m_data, node->left);
			}
			else
			{
				Node* last = node->right;
				while (last->left != nullptr)
				{
					last = last->left;
				}
				node->m_data = last->m_data;
				node->right = remove( last->m_data, node->right);

			}
		}
		else
		{
			if (node->left != nullptr)
			{
				Node* left = node->left;
				delete node;
				return left;
			}
			else if (node->right != nullptr)
			{
				Node* right = node->right;
				delete node;
				return right;
			}
			else
			{
				delete node;
				return nullptr;
			}
		}
	}
	node->height = max(getHeight(node->left), getHeight(node->right)) + 1;

	return node;

}
相关推荐
影寂ldy1 分钟前
C#Dictionary字典
数据结构
Lucky_ldy3 小时前
数据结构从入门到精通:顺序表
数据结构·链表
熬夜敲代码的猫3 小时前
AVL树(C++详解版)
数据结构·c++·算法
并不喜欢吃鱼3 小时前
从零开始 C++-----十一【C++ 数据结构】红黑树全解析:从定义到工程实现(一文搞定,十分详细)
开发语言·数据结构·c++
星恒随风3 小时前
C语言数据结构排序算法详解(上):从插入排序、希尔排序到选择排序、堆排序
c语言·数据结构·笔记·学习·排序算法
迈巴赫车主4 小时前
蓝桥杯21247弹跳鞋java
java·开发语言·数据结构·算法·职场和发展·蓝桥杯
Cthy_hy4 小时前
Python算法竞赛:集合去重+字典映射 核心用法一站式整理
数据结构·python·算法
happymaker06264 小时前
LeetCodeHot100——盛水最多的容器
数据结构·算法·leetcode·双指针·hot100
过期动态4 小时前
【LeetCode 热题 100】三数之和
java·数据结构·算法·leetcode·职场和发展·排序算法
一切皆是因缘际会4 小时前
AI高速迭代下的技术风险与理性突围
大数据·数据结构·人工智能·架构