AVL树插入的简单实现

avl.h

#ifndef _AVL_TREE_H

#define _AVL_TREE_H

struct 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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值