码迷,mamicode.com
首页 > 其他好文 > 详细

平衡树

时间:2016-04-24 10:59:58      阅读:173      评论:0      收藏:0      [点我收藏+]

标签:

#pragma once
template<class K,class V>
struct AVLTreeNode
{
   AVLTreeNode<K, V>* _left;
   AVLTreeNode<K, V>* _right;
   AVLTreeNode<K, V>* _parent;
   K _key;
   V _value;
   int _bf;
   AVLTreeNode(const K&key,const V&value)
    :_key(key), _value(value), _bf(0), _left(NULL), _right(NULL), _parent(NULL)
   {}
};

 

template<class K,class V>

class AVLTree

{

   typedef AVLTreeNode<K, V> Node;

public:  

  AVLTree() :_root(NULL)  

  {}

  bool Insert(const K&key, const V&value)  

 {   

  if (_root == NULL)  

   {    

    _root = new Node(key, value);   

     return true;   

  }   

  Node* parent = NULL;   

  Node* cur = _root;   while (cur)  

   {   

     if (cur->_key > key)    

    {     

      parent = cur;     

      cur = cur->_left;   

     }    

    else if (cur->_key < key)    

    {    

       parent = cur;    

       cur = cur->_right;    

    }    

    else    

    {     

      return false;   

     }  

   }

  cur = new Node(key, value);
  if (parent->_key < key)
  {
     parent->_right = cur;
     cur->_parent = parent;
  }
  else
  {
     parent->_left = cur;
     cur->_parent = parent;
  }
  bool isRotate = false;
  while (parent)
  {
     if (parent->_left == cur)
     {
        parent->_bf--;
     }
     else
     {
        parent->_bf++;
     }
     if (parent->_bf == 0)
     {
        break;
     }
     else if (parent->_bf == 1 || parent->_bf == -1)
     {
        cur = parent;//回溯继续调整平衡因子
        parent = cur->_parent;
     }
     else
     {
        isRotate = true;
        if (parent->_bf == 2)
        {
           if (cur->_bf == 1)
           {
              _RotateL(parent);
           }
           else
           {
              _RotateRL(parent);
           }
        }
        else
        {
           if (cur->_bf == -1)
           {
              _RotateR(parent);
           }
           else
           {
              _RotateLR(parent);
           }
        }
        break;
     }
  }

 if (isRotate)
  {
     Node* ppNode = parent->_parent;
     if (ppNode == NULL)
     {
        _root = parent;
     }
     else
     {
        if (ppNode->_key < parent->_key)
        {
           ppNode->_right = parent;
        }
        else
        {
           ppNode->_left = parent;
        }
     }
     return true;
   }
}

bool IsBalance()

 {   

    return _IsBalance(_root);  

}

 int Height()  

{   

    return _Height(_root);  

}

 void Inorder()  

{   

    return _Inorder(_root);  

}

protected:
 void _RotateL(Node*& parent)
 {
    Node* subR = parent->_right;
    Node* subRL = subR->_left;
    parent->_right = subRL;
    if (subRL)
    {
       subRL->_parent = parent;
    }
    subR->_left = parent;
    subR->_parent = parent->_parent;
    parent->_parent = subR;
    parent->_bf = subR->_bf = 0;
    parent = subR;
 }

void _RotateR(Node*& parent)
 {
    Node* subL = parent->_left;
    Node* subLR = subL->_right;
    parent->_left = subLR;
    if (subLR)
    {
       subLR->_parent = parent;
    }
    subL->_right = parent;
    subL->_parent = parent->_parent;
    parent->_parent = subL;
    parent->_bf = subL->_bf = 0;
    parent = subL;
 } 

 
 void _RotateLR(Node*& parent)
 {
    Node* subL = parent->_left;
    Node* subLR = subL->_right;
    subL->_right = subLR->_left;
    if (subLR->_left)
    {
       subLR->_left->_parent = subL;
    }
    subLR->_left = subL;
    subLR->_parent = subL->_parent;
    subL->_parent = subLR;
    if (subLR->_bf == 0 || subLR->_bf == -1)
    {
       subL->_bf = 0;
    }
    else
    {
       subL->_bf = -1;
    }

   parent->_left = subLR->_right;

     if (subLR->_right)  

   {    

    subLR->_right->_parent = parent;   

  }   

  subLR->_right = parent;   

  subLR->_parent = parent->_parent;   

  parent->_parent = subLR;  

   if (subLR->_bf == 0 || subLR->_bf ==1 )   

  {    

    parent->_bf = 0;  

   }  

   else   

  {    

    parent->_bf = 1;   

  }   

  subLR->_bf = 0;   

  parent = subLR;  

}

void _RotateRL(Node*& parent)
 {
    Node* subR = parent->_right;
    Node* subRL = subR->_left;
    subR->_left = subRL->_right;
    if (subRL->_right)
    {
       subRL->_right->_parent = subR;
    }
    subRL->_right = subR;
    subRL->_parent = subR->_parent;
    subR->_parent = subRL;
    if (subRL->_bf == 0 || subRL->_bf == 1)
    {
       subR->_bf = 0;
    }
    else
    {
       subR->_bf = 1;
    }
    parent->_right = subRL->_left;
    if (subRL->_left)
    {
       subRL->_left->_parent = parent;
    }
    subRL->_left = parent;
    subRL->_parent= parent->_parent;
    parent->_parent = subRL;
    if (subRL->_bf == 0 || subRL->_bf == -1)
    {
       parent->_bf = 0;
    }
    else
    {
       parent->_bf = -1;
    }
    subRL->_bf = 0;
    parent = subRL;
 }

int _Height(Node* root)
 {
    if (root == NULL)
       return 0;
    int left = _Height(root->_left) + 1;
    int right = _Height(root->_right) + 1;
    return left > right ? left : right;
 }

bool _IsBalance(Node* root)
 {
    if (root == NULL)
    {
       return true;
    }
    int left = _Height(root->_left);
    int right = _Height(root->_right);
    int bf = abs(right - left);
    if (bf > 1)
    {
       return false;
    }
    if (bf != abs(root->_bf))
    {
       cout << root->_key << "平衡因子有问题";
       return false;
    }
    return _IsBalance(root->_left) && _IsBalance(root->_right);
 }

void _Inorder(Node* root)
 {
    if (root == NULL)
    {
       return;
    }
    else
    {
       _Inorder(root->_left);
       cout << root->_key << " ";
       _Inorder(root->_right);
    }  
 }

protected:   

  Node* _root;

};

void Test()

{  

   AVLTree<int, int> t;  

  int a[] = { 16, 3, 7, 11, 9, 26, 18, 14, 15 };  

  for (size_t i = 0; i < sizeof(a) / sizeof(int); ++i)  

  {   

    t.Insert(a[i], i);  

  }  

  t.Inorder();  

  cout << endl;  

  cout << t.IsBalance()<< endl;

}

 

平衡树

标签:

原文地址:http://www.cnblogs.com/yuanshuang/p/5426387.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!