#ifndef AVL_TREE_H
#define AVL_TREE_H
#include "dsexceptions.h"
#include <algorithm>
#include <iostream>
using namespace std;
// AvlTree class
//
// CONSTRUCTION: zero parameter
//
// ******************PUBLIC OPERATIONS*********************
// void insert( x ) --> Insert x
// void remove( x ) --> Remove x (unimplemented)
// bool contains( x ) --> Return true if x is present
// Comparable findMin( ) --> Return smallest item
// Comparable findMax( ) --> Return largest item
// boolean isEmpty( ) --> Return true if empty; else false
// void makeEmpty( ) --> Remove all items
// void printTree( ) --> Print tree in sorted order
// ******************ERRORS********************************
// Throws UnderflowException as warranted
template <typename Comparable>
class AvlTree
{
public:
AvlTree() : root{ nullptr }//默认构造函数
{ }
AvlTree(const AvlTree& rhs) : root{ nullptr }//拷贝构造
{
root = clone(rhs.root);
}
AvlTree(AvlTree&& rhs) : root{ rhs.root }//移动构造
{
rhs.root = nullptr;
}
~AvlTree()
{
makeEmpty();
}
/**
* Deep copy.
*/
AvlTree& operator=(const AvlTree& rhs)
{
AvlTree copy = rhs;
std::swap(*this, copy);
return *this;
}
/**
* Move.
*/
AvlTree& operator=(AvlTree&& rhs)
{
std::swap(root, rhs.root);
return *this;
}
/**
* Find the smallest item in the tree.
* Throw UnderflowException if empty.
*/
const Comparable& findMin() const
{
if (isEmpty())
throw UnderflowException{ };
return findMin(root)->element;
}
/**
* Find the largest item in the tree.
* Throw UnderflowException if empty.
*/
const Comparable& findMax() const
{
if (isEmpty())
throw UnderflowException{ };
return findMax(root)->element;
}
/**
* Returns true if x is found in the tree.
*/
bool contains(const Comparable& x) const
{
return contains(x, root);
}
/**
* Test if the tree is logically empty.
* Return true if empty, false otherwise.
*/
bool isEmpty() const
{
return root == nullptr;
}
/**
* Print the tree contents in sorted order.
*/
void printTree() const
{
if (isEmpty())
cout << "Empty tree" << endl;
else
printTree(root);
}
/**
* Make the tree logically empty.
*/
void makeEmpty()
{
makeEmpty(root);
}
/**
* Insert x into the tree; duplicates are ignored.
*/
void insert(const Comparable& x)
{
insert(x, root);
}
/**
* Insert x into the tree; duplicates are ignored.
*/
void insert(Comparable&& x)
{
insert(std::move(x), root);
}
/**
* Remove x from the tree. Nothing is done if x is not found.
*/
void remove(const Comparable& x)
{
remove(x, root);
}
private:
struct AvlNode//节点
{
Comparable element;//元素
AvlNode* left;//左子树
AvlNode* right;//右子树
int height;//高度
AvlNode(const Comparable& ele, AvlNode* lt, AvlNode* rt, int h = 0)//因为构造节点等等知识内部用到,所以只给了此种类型的构造函数
: element{ ele }, left{ lt }, right{ rt }, height{ h } { }
AvlNode(Comparable&& ele, AvlNode* lt, AvlNode* rt, int h = 0)
: element{ std::move(ele) }, left{ lt }, right{ rt }, height{ h } { }//使用std::move而不是move
};
AvlNode* root;//根节点
/**
* Internal method to insert into a subtree.
* x is the item to insert.
* t is the node that roots the subtree.
* Set the new root of the subtree.
*/
/*
*向子树插入元素的内部方法
* x 是要插入的元素
* t 是子树的根节点
*/
void 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);
}
/**
* Internal method to insert into a subtree.
* x is the item to insert.
* t is the node that roots the subtree.
* Set the new root of the subtree.
*/
void 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);
}
/**
* Internal method to remove from a subtree.
* x is the item to remove.
* t is the node that roots the subtree.
* Set the new root of the subtree.
*/
/*
* 内部删除元素方法
* x 是要被删除的元素
* t 是子树的节点
*/
void remove(const Comparable& x, AvlNode*& t)
{
if (t == nullptr)
return; // Item not found; do nothing
if (x < t->element)
remove(x, t->left);
else if (t->element < x)
remove(x, t->right);
else if (t->left != nullptr && t->right != nullptr) // Two children
{
t->element = findMin(t->right)->element;
remove(t->element, t->right);
}
else
{
AvlNode* oldNode = t;
t = (t->left != nullptr) ? t->left : t->right;
delete oldNode;
}
balance(t);
}
static const int ALLOWED_IMBALANCE = 1;//允许的平衡差值(即两子树相减的差)
// Assume t is balanced or within one of being balanced
/*
*调整当前节点的平衡性以及更新高度
*/
void balance(AvlNode*& t)
{
if (t == nullptr)
return;
if (height(t->left) - height(t->right) > ALLOWED_IMBALANCE)//左子树比右子树高
if (height(t->left->left) >= height(t->left->right))//单旋或双旋判断
rotateWithLeftChild(t);
else
doubleWithLeftChild(t);
else
if (height(t->right) - height(t->left) > ALLOWED_IMBALANCE)
if (height(t->right->right) >= height(t->right->left))
rotateWithRightChild(t);
else
doubleWithRightChild(t);
t->height = max(height(t->left), height(t->right)) + 1;
}
/**
* Internal method to find the smallest item in a subtree t.
* Return node containing the smallest item.
*/
/*
*内部寻找子树中最小值方法
* t 是子树根节点
*/
AvlNode* findMin(AvlNode* t) const
{
if (t == nullptr)
return nullptr;
if (t->left == nullptr)
return t;
return findMin(t->left);
}
/**
* Internal method to find the largest item in a subtree t.
* Return node containing the largest item.
*/
AvlNode* findMax(AvlNode* t) const
{
if (t != nullptr)
while (t->right != nullptr)
t = t->right;
return t;
}
/**
* Internal method to test if an item is in a subtree.
* x is item to search for.
* t is the node that roots the tree.
*/
/*
*内部判断元素是否在子树中的递归方法
* x 是要判断的元素
* t 是子树的根节点
*/
bool contains(const Comparable& x, AvlNode* t) const
{
if (t == nullptr)
return false;
else if (x < t->element)
return contains(x, t->left);
else if (t->element < x)
return contains(x, t->right);
else
return true; // Match
}
/****** NONRECURSIVE VERSION*************************
bool contains( const Comparable & x, AvlNode *t ) const
{
while( t != nullptr )
if( x < t->element )
t = t->left;
else if( t->element < x )
t = t->right;
else
return true; // Match
return false; // No match
}
*****************************************************/
/**
* Internal method to make subtree empty.
*/
void makeEmpty(AvlNode*& t)//置子树为空
{
if (t != nullptr)
{
makeEmpty(t->left);
makeEmpty(t->right);
delete t;
}
t = nullptr;
}
/**
* Internal method to print a subtree rooted at t in sorted order.
*/
void printTree(AvlNode* t) const//打印函数,AvlTree所以是中序遍历
{
if (t != nullptr)
{
printTree(t->left);
cout << t->element << endl;
printTree(t->right);
}
}
/**
* Internal method to clone subtree.
*/
AvlNode* clone(AvlNode* t) const//拷贝子树的方法
{
if (t == nullptr)
return nullptr;
else
return new AvlNode{ t->element, clone(t->left), clone(t->right), t->height };
}
// Avl manipulations
/**
* Return the height of node t or -1 if nullptr.
*/
int height(AvlNode* t) const//返回树的高度,若为空则返回-1
{
return t == nullptr ? -1 : t->height;
}
int max(int lhs, int rhs) const//返回最大值
{
return lhs > rhs ? lhs : rhs;
}
/**
* Rotate binary tree node with left child.
* For AVL trees, this is a single rotation for case 1.
* Update heights, then set new root.
*/
/*
*(LL)
* 更新高度,设置新的根节点
*/
void 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;
}
/**
* Rotate binary tree node with right child.
* For AVL trees, this is a single rotation for case 4.
* Update heights, then set new root.
*/
void rotateWithRightChild(AvlNode*& k1)//(RR)
{
AvlNode* k2 = k1->right;
k1->right = k2->left;
k2->left = k1;
k1->height = max(height(k1->left), height(k1->right)) + 1;
k2->height = max(height(k2->right), k1->height) + 1;
k1 = k2;
}
/**
* Double rotate binary tree node: first left child.
* with its right child; then node k3 with new left child.
* For AVL trees, this is a double rotation for case 2.
* Update heights, then set new root.
*/
void doubleWithLeftChild(AvlNode*& k3)//(LR)
{
rotateWithRightChild(k3->left);
rotateWithLeftChild(k3);
}
/**
* Double rotate binary tree node: first right child.
* with its left child; then node k1 with new right child.
* For AVL trees, this is a double rotation for case 3.
* Update heights, then set new root.
*/
void doubleWithRightChild(AvlNode*& k1)//(RR)
{
rotateWithLeftChild(k1->right);
rotateWithRightChild(k1);
}
};
#endif
AvlTree的C++实现
最新推荐文章于 2023-02-06 23:00:04 发布