#ifndef _AVLTREE_
#define _AVLTREE_
#include<algorithm>
/*AVL树:
1.它必须是二叉查找树。
2.每个节点的左子树和右子树的高度差至多为1
AVL树的查找、插入、删除操作在平均和最坏的情况下都是O(logn)
平衡因子:将二叉树上节点的左子树高度减去右子树高度的值称为该节点的平衡因子,BF的取值范围为[-1,1]
最小不平衡子树:距离插入节点最近的,且平衡因子的绝对值大于1的节点为根的子树。
*/
struct AVLTreeNode
{
AVLTreeNode(int value, AVLTreeNode* l, AVLTreeNode* r) :key(value), lchild(l), rchild(r){};
int key;
int height;
AVLTreeNode* lchild;
AVLTreeNode* rchild;
};
class AVLTree
{
public:
AVLTree(); //构造函数
~AVLTree(); //析构函数
void preOrder(); //前序遍历AVL树
void inOrder(); //中序遍历AVL树
void postOrder(); //后序遍历AVL树
void print(); //打印AVL树
void destory(); //销毁AVL树
void insert(int key); //插入指定值的节点
void remove(int key); //移除指定值的节点
AVLTreeNode* search_recurse(int key); //利用递归算法进行指定值的查找
AVLTreeNode* search_iterator(int key); //利用迭代算法进行指定值的查找
int minimum(); //返回AVL中的最小值
int maximum(); //返回AVL中的最大值
int height(); //返回树的高度
private:
AVLTreeNode* root; //AVL树的根节点
private:
void preOrder(AVLTreeNode* pnode) const;
void inOrder(AVLTreeNode* pnode) const;
void postOrder(AVLTreeNode* pnode) const;
void print(AVLTreeNode* pnode, int key, int direction) const;
void destory(AVLTreeNode* & pnode);
AVLTreeNode* insert(AVLTreeNode* &pnode, int key);
AVLTreeNode* remove(AVLTreeNode* & pnode, int key); //删除AVL树中节点pdel,并返回被删除的节点
AVLTreeNode* minimum(AVLTreeNode*pnode)const;
AVLTreeNode* maximum(AVLTreeNode*pnode)const;
int height(AVLTreeNode* pnode);
AVLTreeNode* search_recurse(AVLTreeNode* pnode, int key) const;
AVLTreeNode* search_iterator(AVLTreeNode* pnode, int key) const;
AVLTreeNode* leftRotation(AVLTreeNode* pnode); //单旋:左旋操作
AVLTreeNode* rightRotation(AVLTreeNode* pnode); //单旋:右旋操作
AVLTreeNode* leftRightRotation(AVLTreeNode* pnode); //双旋:先左旋后右旋操作
AVLTreeNode* rightLeftRotation(AVLTreeNode* pnode); //双旋:先右旋后左旋操作
};
int AVLTree::height()
{
return height(root);
}
int AVLTree::height(AVLTreeNode* pnode)
{
if (pnode != nullptr)
return pnode->height;
else
return -1;
}
/*AVL树失衡调整:(节点的插入或删除都有可能导致AVL树失去平衡)
单左旋:旋转围绕最小失衡子树的根节点进行。
在左子树插入左孩子节点*/
AVLTreeNode* AVLTree::leftRotation(AVLTreeNode* pnode)
{
AVLTreeNode* prchild = pnode->rchild;
if (prchild->lchild != nullptr)
pnode->rchild = prchild->lchild;
prchild->lchild = pnode;
//更新节点高低
pnode->height = std::max(height(pnode->lchild), height(pnode->rchild)) + 1;
prchild->height = std::max(height(prchild->lchild), height(prchild->rchild)) + 1;
}
/*右单旋转
在右子树插入右孩子节点*/
AVLTreeNode* AVLTree::rightRotation(AVLTreeNode* pnode)
{
AVLTreeNode* plchild = pnode->lchild;
if (plchild->rchild != nullptr)
pnode->lchild = plchild->rchild;
plchild->lchild = pnode;
pnode->height = std::max(height(pnode->lchild), height(pnode->rchild)) + 1;
plchild->height = std::max(height(plchild->lchild), height(plchild->rchild)) + 1;
}
/*先右旋后左旋:在右子树上插入左孩子导致AVL树失衡*/
AVLTreeNode* AVLTree::rightLeftRotation(AVLTreeNode* pnode)
{
pnode->rchild = rightRotation(pnode->rchild);
return leftRotation(pnode);
}
/*先左旋后右旋:在左子树上插入右孩子导致AVL树失衡*/
AVLTreeNode* AVLTree::leftRightRotation(AVLTreeNode* pnode)
{
pnode->lchild = leftRotation(pnode->lchild);
return rightRotation(pnode);
}
/*插入新节点*/
AVLTreeNode* AVLTree::insert(AVLTreeNode* &pnode, int key)
{
if (pnode == nullptr)
pnode = new AVLTreeNode(key, nullptr, nullptr);
else if(key>pnode->key)
{
pnode->rchild = insert(pnode->rchild, key);
if (height(pnode->rchild) - height(pnode->lchild) == 2)//插入后失衡
{
if (key > pnode->rchild->key)
pnode = leftRotation(pnode);
else if (key < pnode->rchild->key)
pnode = rightLeftRotation(pnode);
}
}
else if (key < pnode->key)
{
pnode->lchild = insert(pnode->lchild, key);
if (height(pnode->lchild) - height(pnode->rchild) == 2)//插入后失衡
{
if (key > pnode->lchild->key)
pnode = rightRotation(pnode);
else if (key < pnode->lchild->key)
pnode = leftRightRotation(pnode);
}
}
pnode->height = std::max(height(pnode->lchild), height(pnode->rchild)) + 1;
return pnode;
}
/*删除节点:删除节点也可能导致AVL树的失衡,实际上删除节点和插入节点是一种互逆的操作
删除右子树的节点导致AVL树失衡时,相当于在左子树插入节点导致AVL树失衡,即情况情况二或情况四。
删除左子树的节点导致AVL树失衡时,相当于在右子树插入节点导致AVL树失衡,即情况情况一或情况三。
另外,AVL树也是一棵二叉排序树,因此在删除节点时也要维护二叉排序树的性质
删除节点时,如果节点同时拥有左子树和右子树,则在高度教低的子树上选择最大(或最小)元素进行替换,这样能保证替换后不会再出现失衡的现象。*/
AVLTreeNode* AVLTree::remove(AVLTreeNode* & pnode, int key)
{
if (pnode != nullptr)
{
if (key == pnode->key)//找到删除节点
{
//因为AVL也是二叉排序树,删除节点要维护其二叉排序树的条件
if (pnode->lchild != nullptr && pnode->rchild != nullptr)
{
//左子树比右子树高,在左子树上选择节点进行替换
if (height(pnode->lchild) > height(pnode->rchild))
{
AVLTreeNode* ppre = maximum(pnode->lchild);
pnode->key = ppre->key;
pnode->lchild = remove(pnode->lchild, ppre->key);
}
else{//在右子树上选择节点进行替换
AVLTreeNode* ppre = maximum(pnode->rchild);
pnode->key = ppre->key;
pnode->rchild = remove(pnode->rchild, ppre->key);
}
}
else{
AVLTreeNode* ptmp = pnode;
if (pnode->lchild != nullptr)
pnode = pnode->lchild;
else if (pnode->rchild != nullptr)
pnode = pnode->rchild;
delete ptmp;
return nullptr;
}
}
else if (key > pnode->key)//要删除的节点比当前点大,则在右子树进行删除
{
pnode->rchild = remove(pnode->rchild, key);//删除了右节点,可能失衡
if (height(pnode->lchild) - height(pnode->rchild) == 2)
{
//相当于在左子树上插入右节点造成失衡
if (height(pnode->lchild->rchild) > height(pnode->lchild->lchild))
pnode = leftRightRotation(pnode);
else
pnode = rightRotation(pnode);
}
}
else if (key < pnode->key)
{
pnode->lchild = remove(pnode->lchild, key);
if (height(pnode->rchild) - height(pnode->lchild) == 2)
{
//相当于在右子树上插入左节点造成的失衡
if (height(pnode->rchild->lchild) - height(pnode->rchild->rchild))
pnode = rightLeftRotation(pnode);
else//相当于在右子树上插入右节点造成的失衡
pnode = leftRotation(pnode);
}
}
return pnode;
}
return nullptr;
}
/*查找元素*/
//递归查找
AVLTreeNode* AVLTree::search_recurse(int key)
{
return search_recurse(root, key);
}
AVLTreeNode* AVLTree::search_recurse(AVLTreeNode* pnode, int key)
{
if (pnode != nullptr)
{
if (key == pnode->key)
return pnode;
else if (key > pnode->key)
return search_recurse(pnode->rchild, key);
else
return search_recurse(pnode->lchild, key);
}
return nullptr;
}
//迭代查找
AVLTreeNode* AVLTree::search_iterator(int key)
{
return search_iterator(root, key);
}
AVLTreeNode* AVLTree::search_iterator(AVLTreeNode* pnode, int key)
{
if (pnode != nullptr)
{
if (pnode->key == key)
return pnode;
else if (key > pnode->key)
pnode = pnode->rchild;
else pnode = pnode->lchild;
}
return nullptr;
}
/*遍历二叉树*/
//前序:根左右
void AVLTree::preOrder()
{
return preOrder(root);
}
void AVLTree::preOrder(AVLTreeNode* pnode)
{
if (pnode!=nullptr)
{
cout << pnode->key;
preOrder(pnode->lchild);
preOrder(pnode->rchild);
}
}
//中序:左根右
void AVLTree::inOrder()
{
return inOrder(root);
}
void AVLTree::inOrder(AVLTreeNode* pnode)
{
if (pnode != nullptr)
{
inOrder(pnode->lchild);
cout << pnode->key;
inOrder(pnode->rchild);
}
}
//后序:左右根
void AVLTree::postOrder()
{
return postOrder(root);
}
void AVLTree::postOrder(AVLTreeNode* pnode)
{
if (pnode != nullptr)
{
postOrder(pnode->lchild);
postOrder(pnode->rchild);
cout << pnode->key;
}
}
//销毁:只有后序
void AVLTree::destory()
{
return destory(root);
}
void AVLTree::destory(AVLTreeNode* & pnode)
{
if (pnode != nullptr)
{
destory(pnode->lchild);
destory(pnode->rchild);
delete pnode;
pnode = nullptr;
}
}
/*求最大最小值:二叉排序树的最小值位于最左节点,最大值位于其最右节点。*/
AVLTreeNode* AVLTree::maximum(AVLTreeNode* pnode) const
{
while (pnode!= nullptr)
{
while (pnode->rchild != nullptr)
pnode = pnode->rchild;
return pnode;
}
return nullptr;
}
int AVLTree::maximum()
{
AVLTreeNode* presult = maximum(root);
if (presult != nullptr)
return presult->key;
}
AVLTreeNode* AVLTree::minimum(AVLTreeNode*pnode)
{
while (pnode != nullptr)
{
while (pnode->lchild != nullptr)
pnode = pnode->lchild;
return pnode;
}
return nullptr;
}
int AVLTree::minimum()
{
AVLTreeNode* presult = minimum(root);
if (presult != nullptr)
return presult->key;
}
#endif
AVL树的基本操作 C++
原文作者:AVL树
原文地址: https://blog.csdn.net/cat1992/article/details/76262318
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
原文地址: https://blog.csdn.net/cat1992/article/details/76262318
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。