avl.h
#ifndef _AVL_TREE_H
#define _AVL_TREE_Hstruct avl_node
{
avl_node(int k);
int key;
char bf;//Hight(left) - Hight(right), balance factor[-1, 0, 1].
avl_node* parent;
avl_node* left;
avl_node* right;
};
class avl_tree
{
public:
avl_tree();
bool insertNode(int key);
void preorderTraversal(avl_node* root);
void output();
private:
bool findKey(int key, avl_node*& node);
void keepBalance(avl_node* node);
avl_node* leftRotation(avl_node* root);
avl_node* rightRotation(avl_node* root);
private:
avl_node* _root;
int _leftRC, _rightRC, _count;
};
#endif
avl.cc
#include "avl.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>
avl_node::avl_node(int k) : key(k), bf(0), parent(NULL), left(NULL), right(NULL) {}
avl_tree::avl_tree() : _root(NULL), _leftRC(0), _rightRC(0), _count(0) {}
bool avl_tree::insertNode(int key)
{
if(NULL==_root) {
_count++;
_root = new avl_node(key);
return true;
}
avl_node* temp = NULL;
if(findKey(key, temp)) //find the same key
return false;
avl_node* newnode = new avl_node(key);
_count++;
newnode->parent = temp;
if(key < temp->key) {
temp->left = newnode;
}
else {
temp->right = newnode;
}
keepBalance(newnode);
return true;
}
bool avl_tree::findKey(int key, avl_node*& node)
{
avl_node* temp = _root;
while(temp!=NULL) {
node = temp;
if(temp->key==key)
return true;
else if(temp->key>key)
temp = temp->left;
else
temp = temp->right;
}
return false;
}
void avl_tree::keepBalance(avl_node* node)
{
assert(node->parent!=NULL);
avl_node* parent = node->parent;
while(parent!=NULL) {
if(node->key<parent->key) {
parent->bf += 1;
switch(parent->bf) {
case 0:
return;
case 1:
break;
case 2:
node = rightRotation(parent);
if(node->parent==NULL) {
printf("change root:%d\n", node->key);
_root = node;
}
return;
}
}
else {
parent->bf -= 1;
switch(parent->bf) {
case -2:
node = leftRotation(parent);
if(node->parent==NULL){
printf("left change root:%d\n", node->key);
_root = node;
}
return;
case -1:
break;
case 0:
return;
}
}
node = parent;
parent = parent->parent;
}
}
avl_node* avl_tree::leftRotation(avl_node* root)
{
_leftRC++;
avl_node* right = root->right;
assert(right!=NULL);
if(1==right->bf) {
right = rightRotation(right);
printf("double rotate:%d, %d, %d\n", root->key, root->right->key, right->key);
}
if(root->parent!=NULL) {
if(root->parent->key < root->key)
root->parent->right = right;
else
root->parent->left = right;
}
root->right = right->left;
right->parent = root->parent;
if(right->left!=NULL)
right->left->parent = root;
right->left = root;
root->parent = right;
root->bf++;
if(right->bf < 0)
root->bf -= right->bf;
right->bf++;
if(root->bf > 0)
right->bf += root->bf;
return right;
}
avl_node* avl_tree::rightRotation(avl_node* root)
{
_rightRC++;
avl_node* left = root->left;
assert(left!=NULL);
if(-1==left->bf)
left = leftRotation(left);
if(root->parent!=NULL) {
if(root->parent->key < root->key)
root->parent->right = left;
else
root->parent->left = left;
}
root->left = left->right;
if(left->right!=NULL)
left->right->parent=root;
left->parent=root->parent;
left->right = root;
root->parent = left;
root->bf--;
if(left->bf > 0)
root->bf -= left->bf;
left->bf--;
if(root->bf < 0)
left->bf += root->bf;
return left;
}
void avl_tree::preorderTraversal(avl_node* root)
{
if(root==NULL)
root=_root;
if(root->left!=NULL)
preorderTraversal(root->left);
assert(root->bf>-2&&root->bf<2);
printf("%d ", root->key);
if(root->right!=NULL)
preorderTraversal(root->right);
}
void avl_tree::output()
{
printf("left rotation:%d, right rotation:%d, node:%d\n", _leftRC, _rightRC, _count);
}
//test part
int main(int argc, char* argv[])
{
srand((int)time(0));
int key[10] = {1,5,2,15,25,33,26,32,9,11};
avl_tree tree;
for(int i=0; i<10000000; i++) {
tree.insertNode(rand());
}
tree.output();
tree.preorderTraversal(NULL);
return 0;
}