#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_TREE
PNode m_pnode;
#endif
PNode m_Root;
BsTreeType data;
bool hight_change;
};
inline BslanceTree::BslanceTree(void)
{
m_Root = NULL;
#ifdef __BINARY_TREE
m_pnode = NULL;
#endif
}
////////////////////////////////////////////////////////////////////////
#ifdef __BINARY_TREE
inline 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_DATA
inline 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;
}
#endif
inline 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: // new
pnode->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: // new
pnode->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 node
BslanceTree::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
AVL平衡树实现
最新推荐文章于 2024-10-05 19:25:32 发布