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