对于二叉查找树,由于不良数据,可能形成很不平衡的树。而且,在删除操作的时候,总是在右子树中寻找节点来代替删除节点,
这样有助于左子树比右子树深,查找时间增加。虽然可以随机选取左子树的最大节点或右子树的最小节点来替代删除节点,来消除不平衡性。
但通过这种做法来消除不平衡并没有被证实。
所以,二叉平衡树应运而生。
.h
struct Node
{
int data;
int height;
Node *left;
Node *right;
};
class AVL
{
public:
AVL();
~AVL();
void Insert(int data);
void Delete(int data);
Node *Find(int data);
Node *FindMin();
Node *FindMax();
void Print();
private:
Node* _Insert(Node* root, int data);
Node* _SingleToRight(Node *K2);
Node* _SingleToLeft(Node *K2);
Node* _DoubleToLeftRight(Node *K3);
Node* _DoubleToRightLeft(Node *K3);
int _Height(Node *root);
int _Max(int a, int b);
void _Print(Node *root);
void _MakeEmpty(Node *root);
Node *_Find(Node *root, int data);
Node *_Delete(Node *root, int data);
Node *_FindMin(Node *root);
Node *_FindMax(Node *root);
int _GetBalanceFactor(Node *root);
Node *_root;
};
.cpp
AVL::AVL()
{
_root = NULL;
}
AVL::~AVL()
{
_MakeEmpty(_root);
}
void AVL::_MakeEmpty(Node *root)
{
if(root != NULL)
{
_MakeEmpty(root->left);
_MakeEmpty(root->right);
delete root;
}
}
void AVL::Insert(int data)
{
_root = _Insert(_root, data);
}
Node *AVL::_Insert(Node *root, int data)
{
if(root == NULL)
{
root = new Node;
root->left = root->right = NULL;
root->data = data;
root->height = 0;
}
else if(data > root->data) //Right
{
root->right = _Insert(root->right, data);
if( (_Height(root->right) - _Height(root->left)) == 2)
{
if(data > root->right->data) //Right
{
root = _SingleToLeft(root);
}
else //Left
{
root = _DoubleToRightLeft(root);
}
}
}
else if(data < root->data) //Left
{
root->left = _Insert(root->left, data);
if( (_Height(root->left) - _Height(root->right)) == 2)
{
if(data < root->left->data) //Left
{
root = _SingleToRight(root);
}
else //Right
{
root = _DoubleToLeftRight(root);
}
}
}
root->height = _Max(_Height(root->left), _Height(root->right)) + 1;
return root;
}
int AVL::_Max(int a, int b)
{
if(a > b)
return a;
else
return b;
}
Node *AVL::_SingleToRight(Node *K2)
{
Node *K1 = K2->left;
K2->left = K1->right;
K1->right = K2;
K1->height = _Max(_Height(K1->left),_Height(K1->right) ) + 1;
K2->height = _Max(_Height(K2->left),_Height(K2->right) ) + 1;
return K1;
}
Node *AVL::_SingleToLeft(Node *K2)
{
Node *K1 = K2->right;
K2->right = K1->left;
K1->left = K2;
K1->height = _Max(_Height(K1->left),_Height(K1->right) ) + 1;
K2->height = _Max(_Height(K2->left),_Height(K2->right) ) + 1;
return K1;
}
Node *AVL::_DoubleToLeftRight(Node *K3)
{
K3->left = _SingleToLeft(K3->left);
Node* K1 = _SingleToRight(K3);
return K1;
}
Node *AVL::_DoubleToRightLeft(Node *K3)
{
K3->right = _SingleToRight(K3->right);
Node *K1 = _SingleToLeft(K3);
return K1;
}
int AVL::_Height(Node *root)
{
if(root == NULL)
return -1;
else
return root->height;
}
void AVL::Print()
{
_Print(_root);
cout << endl;
}
void AVL::_Print(Node *root)
{
if(root != NULL)
{
_Print(root->left);
cout << root->data << " ";
_Print(root->right);
}
}
Node *AVL::Find(int data)
{
return _Find(_root, data);
}
Node *AVL::FindMin()
{
return _FindMin(_root);
}
Node *AVL::_FindMin(Node *root)
{
if(root == NULL)
return NULL;
if(root->left == NULL)
return root;
else
return _FindMin(root->left);
}
Node *AVL::_FindMax(Node *root)
{
if(root == NULL)
return NULL;
if(root->right == NULL)
return root;
else
return _FindMax(root->right);
}
Node *AVL::_Find(Node *root, int data)
{
if(root == NULL)
return NULL;
if(data > root->data)
{
return _Find(root->right, data);
}
else if(data < root->data)
{
return _Find(root->left, data);
}
return root;
}
void AVL::Delete(int data)
{
_root = _Delete(_root, data);
}
Node *AVL::_Delete(Node *root, int data)
{
if(root == NULL)
return NULL;
if(data > root->data)
{
root->right = _Delete(root->right, data);
}
else if(data < root->data)
{
root->left = _Delete(root->left, data);
}
else
{
if(root->left != NULL && root->right != NULL)
{
Node *tmp = _FindMin(root->right);
root->data = tmp->data;
root->right = _Delete(root->right, tmp->data);
}
else
{
Node *del = root;
if(root->left == NULL)
root = root->right;
else if(root->right == NULL)
root = root->left;
delete del;
}
}
if( root == NULL)
return root;
root->height = _Max(_Height(root->left), _Height(root->right)) + 1;
//删除,可以等效为插入失去平衡
//唯一不同的是,需要从删除结点一直比较到根,检查是否平衡
if( _GetBalanceFactor(root) == 2 ) // left
{
if( _GetBalanceFactor(root->left) >= 0)
{
return _SingleToRight(root);
}
else
{
return _DoubleToLeftRight(root);
}
}
else if(_GetBalanceFactor(root) == -2) //right
{
if( _GetBalanceFactor(root->right) <= 0)
{
return _SingleToLeft(root);
}
else
{
return _DoubleToRightLeft(root);
}
}
return root;
}
int AVL::_GetBalanceFactor(Node *root)
{
return _Height(root->left) - _Height(root->right);
}