平衡二叉树是带有平衡条件的二叉查找树,指的是空树或者任一结点左、右高度差的绝对值不超过1的二叉树.
比如:
实现的难点在于,二叉树的平衡旋转
分为四种旋转,RR、LL、LR、RL旋转
#include //栈
#include
#include
#include
using namespace std;
template <typename Comparable>
class AVLTree
{
private:
static const int ALLOWED_IMBLANCE = 1;
struct AVLNode
{
Comparable element;
AVLNode * left;
AVLNode * right;
int height;
AVLNode(const Comparable & theElement, AVLNode *lt, AVLNode *rt,int h = 0)
:element(theElement), left(lt), right(rt),height(h) {}
AVLNode(Comparable && theElement, AVLNode *lt, AVLNode *rt, int h = 0)
:element(std::move(theElement)), left(lt), right(rt),height(h) {}
};
AVLNode * root;
void Insert(const Comparable &x, AVLNode * & t);
void Insert(Comparable && x, AVLNode *&t);
void Insert(initializer_list<Comparable> &d, AVLNode *& t);
void Remove(const Comparable &x, AVLNode *&t);
AVLNode * findMin(AVLNode *t)const;
AVLNode * findMax(AVLNode *t)const;
bool contains(const Comparable &x, AVLNode *t) const;
void makeEmpty(AVLNode * &t);
void PrintTree(AVLNode *t) const;
AVLNode* clone(AVLNode *t)const
{
if (t == nullptr)
return nullptr;
return new AVLNode(t->element, clone(t->left), clone(t->right));
}
void rotateWithLeftChild(AVLNode *& k2);
void rotateWithRightChild(AVLNode *& k2);
void doubleWithLeftChild(AVLNode *&k3);
void doubleWithRightChild(AVLNode *&k3);
void balance(AVLNode*& t);
public:
AVLTree() :root(nullptr) {}
AVLTree(const AVLTree & rhs) :root(nullptr) { root = clone(rhs.root); }
AVLTree(AVLTree && rhs) :root(nullptr) { root = rhs.root;rhs = nullptr;}
~AVLTree() { makeEmpty(); }
const Comparable & findMin() const { return findMin(root)->element; }
const Comparable & findMax() const { findMax(root)->element; }
bool contains(const Comparable & x) const { return contains(x, root); }
bool isEmpty() const { return root == nullptr; }
int height(AVLNode *t) const { return t == nullptr ? -1 : t->height; }
void PrintTree()const { PrintTree(root); }
void makeEmpty() { makeEmpty(root); }
void Insert(const Comparable &x) { Insert(x,root); }
void Insert(Comparable && x) { Insert(x,root); }
void Insert(initializer_list<Comparable>d) { Insert(d, root); }
void Remove(const Comparable &x) { Remove(x, root); }
AVLTree & operator=(const AVLTree & rhs)
{
if (this != &rhs)
{
makeEmpty();
root = clone(rhs.root);
}
return *this;
}
AVLTree & operator=(AVLTree && rhs)
{
if (this != &rhs)
{
makeEmpty();
root = rhs.root;
rhs.root = nullptr;
}
return *this;
}
friend int Max(int a, int b);
};
int Max(int a, int b)
{
return (a > b) ? a : b;
}
template<typename Comparable>
void AVLTree<Comparable>::Insert(const Comparable & x, AVLNode *& t)
{
if (t == nullptr)
{
t = new AVLNode(x, nullptr, nullptr);
}
else if (x < t->element)
Insert(x, t->left);
else if (t->element < x)
Insert(x, t->right);
balance(t);
}
template<typename Comparable>
void AVLTree<Comparable>::Insert(Comparable && x, AVLNode *& t)
{
if (t == nullptr)
{
t = new AVLNode(std::move(x), nullptr, nullptr);
}
else if (x < t->element)
Insert(std::move(x), t->left);
else if (t->element < x)
Insert(std::move(x), t->right);
balance(t);
}
template<typename Comparable>
void AVLTree<Comparable>::Insert(initializer_list<Comparable> &d, AVLNode *& t)
{
for (auto p = d.begin(); p != d.end(); p++)
{
Insert(*p, t);
}
}
template<typename Comparable>
void AVLTree<Comparable>::Remove(const Comparable & x, AVLNode *& t)
{
if (t == nullptr) //没找到相应的项什么都不做
return;
if (x < t->element)
Remove(x, t->left);
else if (x > t->element)
Remove(x, t->right);
else if (t->left != nullptr && t->right != nullptr)//找到了 但是有两个儿子
{//取右子树的最小元素替代 或者左子树的最大元素,好处是右子树的最小元素一定在右子树的最左边,左子树的最大元素一定在左子树的最右边
t->element = findMin(t->right)->element;//在右子树中找到最小的元素填充删除结点
Remove(t->element, t->right);//在删除节点的右子树中删除最小元素.
}
else //有一个儿子 或者没有
{
AVLNode * oldNode = t;
t = (t->left != nullptr) ? t->left : t->right; //如果有儿子,就让儿子接上,如果没有那t就设置为nullptr
delete oldNode;
}
balance(t);
}
template<typename Comparable>
typename AVLTree<Comparable>::AVLNode *
AVLTree<Comparable>::findMin(AVLNode * t) const
{
//递归版本
//if (t == nullptr)
// return nullptr;
//if (t->left == nullptr)
// return t;
//return findMin(t->left);
//非递归版本
if (t != nullptr)
while (t->left != nullptr)
t = t->right;
return t;
}
template<typename Comparable>
typename AVLTree<Comparable>::AVLNode *
AVLTree<Comparable>::findMax(AVLNode * t)const
{
//递归版本
/*if (t == nullptr)
return;
if (t->right == nullptr)
return t;
return findMax(t->right);*/
if (t != nullptr)
while (t->right != nullptr)
t = t->right;
return t;
}
template<typename Comparable>
bool AVLTree<Comparable>::contains(const Comparable & x, AVLNode * t) const
{
//递归版本
/*if (t == nullptr)
return false;
else if (x < t->element)
return contains(x, t->left);
else if (x > t->element)
return contains(x, t->right);
else
retu true;*/
//非递归版本
while (t != nullptr)
{
if (x < t->element)
t = t->left;
else if (x > t->element)
t = t->right;
else
return true;
}
return false;
}
template<typename Comparable>
void AVLTree<Comparable>::makeEmpty(AVLNode *& t)
{
if (t != nullptr)
{
makeEmpty(t->left);
makeEmpty(t->right);
delete t;
}
t = nullptr;
}
template<typename Comparable>
void AVLTree<Comparable>::PrintTree(AVLNode * t) const
{
//递归先序遍历
if (t != nullptr)
{
std::cout << t->element << " "; //先序遍历
PrintTree(t->left);
PrintTree(t->right);
}
//非递归的先序遍历, 使用栈
//AVLNode * temp = t;
//stacks;
//while (temp || !s.empty())
//{
// while (temp) //一直向左将沿途结点压入栈
// {
// s.push(temp);
// temp = temp->left;
// }
// if (!s.empty())
// {
// temp = s.top();
// s.pop();
// std::cout << temp->element << " "; //先序遍历
// temp = temp->right;
// }
//}
//层序遍历,使用队列
//AVLNode * temp;
//queueq;
//if (t == nullptr)
// return;
//q.push(t);
//while (!q.empty())
//{
// temp = q.front();
// q.pop();
// std::cout << temp->element << " ";
// if (temp->left)
// q.push(temp->left);
// if (temp->right)
// q.push(temp->right);
//}
}
template<typename Comparable>
void AVLTree<Comparable>::rotateWithLeftChild(AVLNode *& k2)//左旋
{
AVLNode *k1 = k2->left;
k2->left = k1->right;
k1->right = k2;
k2->height = Max(height(k2->left), height(k2->right)) + 1;
k1->height = Max(height(k1->left), k2->height) + 1;
k2 = k1;//把所有的设置都变为改变后的设置
}
template<typename Comparable>
void AVLTree<Comparable>::rotateWithRightChild(AVLNode *& k2)//右旋
{
AVLNode *k1 = k2->right;
k2->right = k1->left;
k1->left = k2;
k2->height = Max(height(k2->right), height(k2->left)) + 1;
k1->height = Max(height(k1->right), k2->height) + 1;
k2 = k1;
}
template<typename Comparable>
void AVLTree<Comparable>::doubleWithLeftChild(AVLNode *& k3)//左右旋转
{
rotateWithRightChild(k3->left);
rotateWithLeftChild(k3);
}
template<typename Comparable>
void AVLTree<Comparable>::doubleWithRightChild(AVLNode *& k3)//右左旋转
{
rotateWithLeftChild(k3->right);
rotateWithRightChild(k3);
}
template<typename Comparable>
void AVLTree<Comparable>::balance(AVLNode *& t)
{
if (t == nullptr)
{
return;
}
if (height(t->left) - height(t->right) > ALLOWED_IMBLANCE)
if (height(t->left->left) >= height(t->left->right))
rotateWithLeftChild(t);
else
doubleWithLeftChild(t);
else if(height(t->right) - height(t->left) > ALLOWED_IMBLANCE)
if (height(t->right->right) >= height(t->right->left))
rotateWithRightChild(t);
else
doubleWithRightChild(t);
t->height = max(height(t->left), height(t->right)) + 1;
}
public class AVLTree<T> where T : IComparable<T>
{
public class AVLNode
{
public T element;
public AVLNode Left;
public AVLNode Right;
public int Height;
public AVLNode(T e, AVLNode l, AVLNode r,int h = 0)
{
element = e;
Left = l;
Right = r;
Height = h;
}
};
private const int ALLOWED_IMBLANCE = 1;
private AVLNode Root;
public AVLTree()
{
Root = null;
}
public AVLTree(AVLTree<T> other)
{
Root = Clone(other.Root);
}
~AVLTree()
{
MakeEmpty();
}
private void Insert(T x,ref AVLNode t)
{
if(t == null)
{
t = new AVLNode(x, null, null);
}
else if (x.CompareTo(t.element) < 0)
{
Insert(x, ref t.Left);
if (Height(t.Left) - Height(t.Right) == 2)
if (x.CompareTo(t.Left.element) < 0)
RotateWithLeftChild(ref t);
else
DoubleWithLeftChild(ref t);
}
else if(x.CompareTo(t.element) > 0)
{
Insert(x, ref t.Right);
if (Height(t.Right) - Height(t.Left) == 2)
if (x.CompareTo(t.Right.element) > 0)
RotateWithRightChild(ref t);
else
DoubleWithRightChild(ref t);
}
t.Height = Max(Height(t.Left), Height(t.Right)) + 1;
}
private void Insert(ref AVLNode t,params T[] paramList)
{
foreach(var temp in paramList)
{
Insert(temp, ref t);
}
}
private void Remove(T x, ref AVLNode t)
{
if(t == null)
{
return;
}
if (x.CompareTo(t.element) < 0)
{
Remove(x, ref t.Left);
}
else if(x.CompareTo(t.element) > 0)
{
Remove(x, ref t.Right);
}
else if(t.Left != null && t.Right != null)
{
t.element = FindMin(t);
Remove(t.element, ref t.Right);
}
else
{
AVLNode oldNode = t;
t = t.Left ?? t.Right;
oldNode = null;
}
Balance(ref t);
}
private T FindMin(AVLNode t)
{
if (t != null)
while (t.Left != null)
t = t.Right;
return t.element;
}
private T FindMax(AVLNode t)
{
if (t != null)
while (t.Right != null)
t = t.Right;
return t.element;
}
private bool Contains(T x, AVLNode t)
{
while (t != null)
{
if (x.CompareTo(t.element) < 0)
t = t.Left;
else if (x.CompareTo(t.element) > 0)
t = t.Right;
else
return true;
}
return false;
}
private void MakeEmpty(ref AVLNode t)
{
if(t != null)
{
MakeEmpty(ref t.Left);
MakeEmpty(ref t.Right);
t = null;
}
}
private void PrintTree(AVLNode t)
{
if(t != null)
{
Console.WriteLine($"{t.element} ");
PrintTree(t.Left);
PrintTree(t.Right);
}
}
private AVLNode Clone(AVLNode t)
{
if(t == null)
{
return null;
}
return new AVLNode(t.element, Clone(t.Left), Clone(t.Right));
}
private int Max(int a, int b)
{
return (a > b) ? a : b;
}
private void RotateWithLeftChild(ref AVLNode k2)//左旋
{
AVLNode k1 = k2.Left;
k2.Left = k1.Right;
k1.Right = k2;
k2.Height = Max(Height(k2.Left), Height(k2.Right)) + 1;
k1.Height = Max(Height(k1.Left), k2.Height) + 1;
k2 = k1;
}
private void RotateWithRightChild(ref AVLNode k2)
{
AVLNode k1 = k2.Right;
k2.Right = k1.Left;
k1.Left = k2;
k2.Height = Max(Height(k2.Right), Height(k2.Left)) + 1;
k1.Height = Max(Height(k1.Right), k2.Height) + 1;
k2 = k1;
}
private void DoubleWithLeftChild(ref AVLNode k3)
{
RotateWithRightChild(ref k3.Left);
RotateWithLeftChild(ref k3);
}
private void DoubleWithRightChild(ref AVLNode k3)
{
RotateWithLeftChild(ref k3.Right);
RotateWithRightChild(ref k3);
}
private void Balance(ref AVLNode t)
{
if (t == null)
{
return;
}
if (Height(t.Left) - Height(t.Right) > ALLOWED_IMBLANCE)
if (Height(t.Left.Left) >= Height(t.Left.Right))
RotateWithLeftChild(ref t);
else
DoubleWithLeftChild(ref t);
else if (Height(t.Right) - Height(t.Left) > ALLOWED_IMBLANCE)
if (Height(t.Right.Right) >= Height(t.Right.Left))
RotateWithRightChild(ref t);
else
DoubleWithRightChild(ref t);
t.Height = Max(Height(t.Left), Height(t.Right)) + 1;
}
public bool Contains(T x)
{
return Contains(x, Root);
}
public bool IsEmpty()
{
return Root == null;
}
public void PrintTree()
{
PrintTree(Root);
}
public void MakeEmpty()
{
MakeEmpty(ref Root);
}
public void Insert(T x)
{
Insert(x, ref Root);
}
public void Insert(params T[] paramList)
{
Insert(ref Root, paramList);
}
public void Remove(T x)
{
Remove(x, ref Root);
}
public T FindMin()
{
return FindMin(Root);
}
public T FindMax()
{
return FindMax(Root);
}
public int Height(AVLNode t) { return t == null ? -1 : t.Height; }
}