AVL树
- 一般的二叉树只有在输入完全随机时才能实现nlogn的复杂度,最坏可到达n^2
- AVL树保证每个子根的左右子树的高度最大相差1,从而保证了nlogn的复杂度
- 除了插入和删除外,其余操作的实现和普通二叉树无异
- 主要多的操作就是左右旋转来实现再平衡
- 和红黑树相比,AVL树的搜索操作更快,但是插入和删除操作更慢
#pragma once
#ifndef AVL_H
#define AVL_H
#include <iostream>
template<typename Comparable>
class AVL
{
struct Node
{
Comparable elements;
Node* left;
Node* right;
size_t height;
Node(Comparable Elements, Node* Left, Node* Right, size_t Height)
:elements(Elements), left(Left), right(Right), height(Height) {}
};
Node* root;
public:
AVL();
void insert(Comparable x);
void remove(Comparable x);
private:
void insert(Comparable&& x, Node* & t);
int height(Node* t);
int balanceFactor(Node* t);
void changeHeight(Node* t);
void balance(Node* t);
void LLrotation(Node* & t);
void LRrotation(Node* & t);
void RRrotation(Node* & t);
void RLrotation(Node* & t);
void remove(Comparable&& x, Node* & t);
};
#endif
#include "AVL.h"
template<typename Comparable>
AVL<Comparable>::AVL() :
root(nullptr) {}
template<typename Comparable>
void AVL<Comparable>::insert(Comparable x)
{
insert(std::move(x), root);
}
template<typename Comparable>
void AVL<Comparable>::remove(Comparable x)
{
remove(std::move(x), root);
}
template<typename Comparable>
void AVL<Comparable>::remove(Comparable&& x, Node* & t)
{
if (t == nullptr)
return;
if (x < t->elements)
remove(std::move(x), t->left);
else if (x > t->elements)
remove(std::move(x), t->right);
else
{
if (t->left == nullptr && t->right == nullptr)
{
delete t;
t = nullptr;
}
else if (t->left == nullptr || t->right == nullptr)
{
auto temp = t;
if (t->left == nullptr)
{
t = t->right;
delete temp;
}
else
{
t = t->left;
delete temp;
}
}
else
{
auto & repalce = findMax(t->left);
t->elements = repalce->elements;
auto temp = repalce;
repalce = repalce->left;
delete temp;
}
}
balance(t);
}
template<typename Comparable>
void AVL<Comparable>::insert(Comparable&& x, Node* & t)
{
if (t == nullptr)
t = new Node(std::move(x), nullptr, nullptr, 0);
else if (x < t->elements)
insert(std::move(x), t->left);
else if (x > t->elements)
insert(std::move(x), t->right);
else
;
balance(t);
}
template<typename Comparable>
int AVL<Comparable>::height(Node* t)
{
if (t == nullptr)
return -1;
else
return t->height;
}
template<typename Comparable>
int AVL<Comparable>::balanceFactor(Node* t)
{
if (t == nullptr)
return 0;
return t->left->height - t->right->height;
}
template<typename Comparable>
void AVL<Comparable>::changeHeight(Node* t)
{
if (t == nullptr)
return;
int left = height(t->left);
int right = height(t->right);
t->height = left < right ? right : left;
}
template<typename Comparable>
void AVL<Comparable>::balance(Node* t)
{
if (t == nullptr)
return;
int factor = balanceFactor(t);
if (factor > 1)
{
if (balanceFactor(t->left) >= 0)
LLrotation(t);
else
LRrotation(t);
}
else if (factor < -1)
{
if (balanceFactor(t->right) <= 0)
RRrotation(t);
else
RLrotation(t);
}
else
changeHeight(t);
}
template<typename Comparable>
void AVL<Comparable>::RRrotation(Node* & t)
{
auto right = t->right;
auto rightLeft = right->left;
t->right = rightLeft;
right->left = t;
t = right;
changeHeight(t);
changeHeight(t->right);
}
template<typename Comparable>
void AVL<Comparable>::LLrotation(Node* & t)
{
auto left = t->left;
auto leftRight = left->right;
t->left = leftRight;
left->right = t;
t = left;
changeHeight(t);
changeHeight(t->left);
}
template<typename Comparable>
void AVL<Comparable>::RLrotation(Node* & t)
{
LLrotation(t->left);
RRrotation(t);
}
template<typename Comparable>
void AVL<Comparable>::LRrotation(Node* & t)
{
RRrotation(t->right);
LLrotation(t);
}
标准红黑树
- 实现原理来自《算法导论》
- 每个子根的左右子树高度最多相差一倍
- C++中的STL标准库中的set和map就是用红黑树实现的
(具体代码待续)
左倾红黑树
- 实现来自于《算法》第四版
- 规定红色节点只能为左节点
- 实现更为简单,但是性能比标准版较差
(具体代码待续)