AVL平衡树实现

来源:互联网 发布:接吻会传染什么病知乎 编辑:程序博客网 时间:2024/05/01 15:11
 
#ifndef BELANCETREE_INCLUDED#define BELANCETREE_INCLUDED#include <string>//#include <cstdlib>using namespace std;#define ERROR 0#define LH +1 //左高#define RH -1 //右高#define EH 0  //等高//#define __BINARY_TREE  //是否使用二叉树#define __STRING_DATA   //data是否为string类型typedef string BsTreeType;struct BsTreeNode{     short bf; //节点平衡因子     struct BsTreeNode *lchild, *rchild;     BsTreeType data;};typedef BsTreeNode Node;typedef Node* PNode;class BslanceTree{   public:    inline BslanceTree(void);    //排序二叉树#ifdef __BINARY_TREE    inline bool AddNode(const BsTreeType & data); //非字符串型    inline bool delNode(const BsTreeType & data);    inline bool FindNode(const BsTreeType & data);    inline bool TraverBsTree(const PNode & pnode);#endif    //bbst平衡二叉树bool   InsertAvl(const BsTreeType & data);    inline PNode & GetRoot(void);bool   DelAvl(const BsTreeType & data);    inline ~BslanceTree(void);   protected:    inline bool GR(const string & sdata, const string & ddata);    inline bool EQ(const string & sdata, const string & ddata);#ifndef __STRING_DATA    inline bool GR(const BsTreeType & sdata, const BsTreeType & ddata);    inline bool EQ(const BsTreeType & sdata, const BsTreeType & ddata);#endif    inline void CleanTree(PNode & pnode);           bool DelAvlNode(PNode & pnode);   bool InsertAVL(PNode & pnode);    inline void RightBalance(PNode & pnode);    inline void  LeftBalance(PNode & pnode);    inline void     L_Rotate(PNode & pnode);    inline void     R_Rotate(PNode & pnode);  private:#ifdef __BINARY_TREEPNode m_pnode;#endif    PNode m_Root;BsTreeType data;bool hight_change;};inline BslanceTree::BslanceTree(void){    m_Root =  NULL;#ifdef __BINARY_TREEm_pnode = NULL;#endif}////////////////////////////////////////////////////////////////////////#ifdef __BINARY_TREEinline bool BslanceTree::AddNode(const BsTreeType & data){   PNode pnode = new Node;   if (pnode == NULL)      return false;   pnode->lchild = NULL;   pnode->rchild = NULL;   pnode->data   = data;   if (m_Root == NULL)    {        m_Root = pnode;        return true;    }   m_pnode = NULL;   if ( BslanceTree::FindNode(data) ) //node have been create      return true;   if (m_pnode == NULL)      return false;   if (BslanceTree::GR(m_pnode->data, data))      m_pnode->rchild = pnode;   else      m_pnode->lchild = pnode;   return true;}inline bool BslanceTree::FindNode(const BsTreeType & data){//not string type    m_pnode    = m_Root;    PNode next = m_pnode;    while (next)    {        if (BslanceTree::EQ(next->data, data))           return true;        m_pnode = next;        if (BslanceTree::GR(next->data, data))           next = next->rchild; //right big and left small        else           next = next->lchild;    }    return false;}inline bool BslanceTree::delNode(const BsTreeType & data){   if ( BslanceTree::FindNode(data) )   {       if (m_pnode == NULL)          return false;       if (m_pnode->lchild == NULL)       {           if (m_pnode->rchild != NULL)   {   PNode p = m_pnode;               m_pnode = m_pnode->rchild;   delete p;   p = NULL;   }           else   {             delete m_pnode;             m_pnode = NULL;   }           return true;       }       else       {           if (m_pnode->rchild == NULL)           {     PNode p = m_pnode;             m_pnode = m_pnode->lchild;             delete p;             p = NULL;           }           else           {  PNode pre = m_pnode->lchild;  while (pre->rchild)pre = pre->rchild;  if (pre == NULL)  return false;  m_pnode->data = pre->data;//交换值  delete pre;  pre = NULL;           }//else         return true;       }   }   return false;}inline bool BslanceTree::TraverBsTree(const PNode & pnode){    if (pnode != NULL)    {      BslanceTree::TraverBsTree(pnode->lchild);  cout << "data : " << pnode->data << endl;      BslanceTree::TraverBsTree(pnode->rchild);    }}#endif////////////__BINARY_TREE//////////////////////////#ifndef __STRING_DATAinline bool BslanceTree::GR(const BsTreeType & sdata, const BsTreeType & ddata){    return sdata > ddata ? true : false;}inline bool BslanceTree::EQ(const BsTreeType & sdata, const BsTreeType & ddata){    return sdata == ddata ? true : false;}#endifinline bool BslanceTree::GR(const string & sdata, const string & ddata){    if (!sdata.size() || !ddata.size())       exit(ERROR);    return strcmp(sdata.c_str(), ddata.c_str()) > 0 ? true : false;}inline bool BslanceTree::EQ(const string & sdata, const string & ddata){    if (!sdata.size() || !ddata.size())       exit(ERROR);    return strcmp(sdata.c_str(), ddata.c_str()) == 0 ? true : false;}inline BslanceTree::~BslanceTree(void){    BslanceTree::CleanTree(m_Root);}inline void BslanceTree::CleanTree(PNode & pnode){    if (pnode != NULL)    {        BslanceTree::CleanTree(pnode->lchild);        BslanceTree::CleanTree(pnode->rchild);        delete pnode;        pnode = NULL;    }}bool BslanceTree::InsertAVL(PNode & pnode){    if (pnode == NULL)    {      pnode = new Node;      if (pnode == NULL)        exit(ERROR);      pnode->data = BslanceTree::data;      pnode->lchild = pnode->rchild = NULL;      pnode->bf = EH, BslanceTree::hight_change = true;    }    else    {        if ( BslanceTree::EQ(pnode->data, BslanceTree::data) )        {//节点已经存在            BslanceTree::hight_change = false;            return false;        }        if ( BslanceTree::GR(BslanceTree::data, pnode->data) )        {//插入到右子树中            if ( !BslanceTree::InsertAVL(pnode->rchild) )               return false;            if (BslanceTree::hight_change)            {//已经插入到右子树中而且树已经长高                switch (pnode->bf)                {                    case LH:  //原左子树比右子树高,现在等高                        pnode->bf = EH; BslanceTree::hight_change = false; break;                    case EH:  //原本左右子树等高,现在右子树比左子树要高, 所以树长高                        pnode->bf = RH; BslanceTree::hight_change = true; break;                    case RH:  //原来右子树比左子树要高,需要作平衡处理                        BslanceTree::RightBalance(pnode);                        BslanceTree::hight_change = false; break;//bf的变化由函数RightBalance(pnode)说了算                }//switch            }//if_t        }//if_B        else        {//插入到左子树中            if ( !BslanceTree::InsertAVL(pnode->lchild) )               return false;            if (BslanceTree::hight_change)            {                switch (pnode->bf)                {                    case LH:  //原来左子树比右子树高,需要作平衡处理                        BslanceTree::LeftBalance(pnode);                        BslanceTree::hight_change = false; break;//bf的变化由函数LeftBalance(pnode)说了算                    case EH:  //原来右子树与左子树等高,现在左子树长高,所以树长高                        pnode->bf = LH; BslanceTree::hight_change = true; break;                    case RH:  //原来右子树比左子树要高,现在要变成等高                        pnode->bf = EH; BslanceTree::hight_change = false; break;                }//switch            }//if_t        }//else    }//else    return true;}inline void BslanceTree::RightBalance(PNode & pnode){//右平衡处理    PNode rc = pnode->rchild;    switch (rc->bf)    {        case RH: //新插入的节点在pnode右孩子的右子树,要作单左旋转处理            pnode->bf = rc->bf = EH;            BslanceTree::L_Rotate(pnode); break;case EH: // newpnode->bf = RH, rc->bf = LH;BslanceTree::L_Rotate(pnode); break;        case LH: //新插入的节点在右孩子的左子树上,要作双旋转处理            PNode ld = rc->lchild;  //ld指向pnode右孩子的左子树的根            switch (ld->bf)            {                case LH: pnode->bf = EH; rc->bf = RH; break;                case EH: pnode->bf = EH; rc->bf = EH; break;                case RH: pnode->bf = LH; rc->bf = EH;            }//sw_ld            ld->bf = EH;            BslanceTree::R_Rotate(pnode->rchild);            BslanceTree::L_Rotate(pnode);    }//sw_ld}inline void BslanceTree::LeftBalance(PNode & pnode){//左平衡处理    PNode lc = pnode->lchild;    switch (lc->bf)    {        case LH: //新插入的节点在左子树,需要单右旋转处理            pnode->bf = lc->bf = EH;            BslanceTree::R_Rotate(pnode); break;case EH: // newpnode->bf =LH, lc->bf = RH;BslanceTree::R_Rotate(pnode); break;        case RH: //新插入的节点在右子树,要作双旋转处理            PNode rd = lc->rchild; //rd为pnode左孩子的右子树的根            switch (rd->bf)            {                case LH: lc->bf = EH; pnode->bf = RH; break;                case EH: lc->bf = pnode->bf = EH; break;                case RH: lc->bf = LH; pnode->bf = EH; break;            }            rd->bf = EH;            BslanceTree::L_Rotate(pnode->lchild);            BslanceTree::R_Rotate(pnode);    }//sw_lc}inline void BslanceTree::L_Rotate(PNode & pnode){//向左旋转,pnode最终还是指向更新后的根节点    PNode rc = pnode->rchild;    pnode->rchild = rc->lchild;    rc->lchild = pnode;    pnode = rc;  //更新根节点}inline void BslanceTree::R_Rotate(PNode & pnode){//向右旋转,pnode最终还是指向更新后的根节点    PNode lc = pnode->lchild;    pnode->lchild = lc->rchild;    lc->rchild = pnode;    pnode = lc;}bool BslanceTree::DelAvlNode(PNode & pnode){if (pnode == NULL)return false;if ( BslanceTree::EQ(pnode->data, BslanceTree::data) ){//delete nodeBslanceTree::hight_change = true; //树变矮if (pnode->lchild == NULL){if (pnode->rchild != NULL)pnode = pnode->rchild;else{delete pnode;pnode = NULL;}return true;}else{if (pnode->rchild == NULL)pnode = pnode->lchild;else{//查找前驱PNode pre = pnode->lchild;while (pre->rchild)pre = pre->rchild;//交换值pnode->data = pre->data;BslanceTree::data = pre->data;if ( !BslanceTree::DelAvlNode(pnode->lchild) )return false;if (BslanceTree::hight_change){//变矮switch (pnode->bf){case LH: //较高的子树被缩短pnode->bf = EH;cout << "371\n";BslanceTree::hight_change = true; break;break;case EH: //原来平等pnode->bf = RH;cout << "376\n";BslanceTree::hight_change = false; break;case RH: //较低的子树被缩短if (pnode->rchild != NULL)if (pnode->rchild->bf == EH)BslanceTree::hight_change = false;BslanceTree::RightBalance(pnode); cout << "383\n";break;}//sw_pn}}//else return true;}//else}//if_Bs//m_ptemp_node = pnode; //保存父节点if ( BslanceTree::GR(BslanceTree::data, pnode->data) ){//右子树if ( !BslanceTree::DelAvlNode(pnode->rchild) )return false;if (BslanceTree::hight_change){//变矮switch (pnode->bf){case LH: //较低的子树被缩短if (pnode->lchild != NULL)if (pnode->lchild->bf == EH)BslanceTree::hight_change = false;BslanceTree::LeftBalance(pnode);cout << "405\n";break;case EH: //原来平等pnode->bf = LH;cout << "409\n";BslanceTree::hight_change = false; break;case RH: //较高的子树被缩短pnode->bf = EH;cout << "413\n";BslanceTree::hight_change = true; break;}//sw_pn}}else{if ( !BslanceTree::DelAvlNode(pnode->lchild) )return false;if (BslanceTree::hight_change){//变矮switch (pnode->bf){case LH: //较高的子树被缩短pnode->bf = EH;cout << "403\n";BslanceTree::hight_change = true; break;break;case EH: //原来平等pnode->bf = RH;cout << "409\n";BslanceTree::hight_change = false; break;case RH: //较低的子树被缩短if (pnode->rchild != NULL)if (pnode->rchild->bf == EH)BslanceTree::hight_change = false;BslanceTree::RightBalance(pnode); cout << "413\n";break;}//sw_pn}}return true;}inline PNode & BslanceTree::GetRoot(void){    return m_Root;}bool BslanceTree::DelAvl(const BsTreeType & data){BslanceTree::data = data;BslanceTree::hight_change = true;if ( !BslanceTree::DelAvlNode(m_Root) )return false;return true;}bool BslanceTree::InsertAvl(const BsTreeType & data){BslanceTree::data = data;BslanceTree::hight_change = true;if ( !BslanceTree::InsertAVL(m_Root) )return false;return true;}#endif // BELANCETREE_INCLUDED