平衡二叉树(AVL树)的简单实现

本文介绍了一个平衡二叉树(AVL树)的C++实现,包括插入、查找、旋转等核心操作,并提供了一个简单的测试案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
#include
<stdlib.h>

template
<typenameT>
classCAVLTree;

template
<typenameT>
classCAVLTreeNode
ExpandedBlockStart.gifContractedBlock.gif
{
public:
CAVLTreeNode(
constT&item,CAVLTreeNode<T>*lptr=NULL,CAVLTreeNode<T>*rptr=NULL,intbalfac=0):data(item),left(lptr),right(rptr),balanceFactor(balfac)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
}

CAVLTreeNode
<T>*Left(void)const
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
returnleft;
}

CAVLTreeNode
<T>*Right(void)const
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
returnright;
}

intGetBalanceFactor()const
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
returnthis->balanceFactor;
}

friend
classCAVLTree<T>;
public:
Tdata;
//数据
private:
CAVLTreeNode
<T>*left;//左子树
CAVLTreeNode<T>*right;//右子树
intbalanceFactor;//平衡因子
CAVLTreeNode<T>*&Left(void)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
returnleft;
}

CAVLTreeNode
<T>*&Right(void)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
returnright;
}


}
;

constintLEFTHEAVY=-1;
constintBALANCE=0;
constintRIGHTHEAVY=1;

template
<typenameT>
classCAVLTree
ExpandedBlockStart.gifContractedBlock.gif
{
public:
CAVLTree(
void);
CAVLTree(
constCAVLTree<T>&tree);
CAVLTree
&operator=(constCAVLTree&rhs);
voidInsert(constT&item);
voidClearTree();//清空树
boolContains(constT&item);//是否包含数据
CAVLTreeNode<T>*FindNode(constT&item,CAVLTreeNode<T>*&parent)const;//寻找节点
CAVLTreeNode<T>*FindMin()const;//找最小值
CAVLTreeNode<T>*FindMax()const;//找最大值
voidPrintTree();//前序遍历树(非递归)
virtual~CAVLTree(void);

protected:
CAVLTreeNode
<T>*GetAVLTreeNode(constT&item,CAVLTreeNode<T>*lptr=NULL,CAVLTreeNode<T>*rptr=NULL);
CAVLTreeNode
<T>*CopyTree(CAVLTreeNode<T>*t);//拷贝树
voidFreeTreeNode(CAVLTreeNode<T>*p);//释放树节点
voidDeleteTree(CAVLTreeNode<T>*t);//删除树

//旋转
voidSingleRotateLeft(CAVLTreeNode<T>*&p);
voidSingleRotateRight(CAVLTreeNode<T>*&p);
voidDoubleRotateLeft(CAVLTreeNode<T>*&p);
voidDoubleRotateRight(CAVLTreeNode<T>*&p);

voidUpdateLeftTree(CAVLTreeNode<T>*&tree,int&reviseBalanceFactor);
voidUpdateRightTree(CAVLTreeNode<T>*&tree,int&reviseBalanceFactor);
voidAVLInsert(CAVLTreeNode<T>*&tree,CAVLTreeNode<T>*newnode,int&reviseBalanceFactor);

private:
CAVLTreeNode
<T>*root;//平衡二叉树树根
intsize;//树节点个数
}
;

ContractedBlock.gifExpandedBlockStart.gif平衡二叉树实现代码
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->#include"BinSTree.h"
#include
<iostream>
#include
<stack>
usingnamespacestd;

ExpandedBlockStart.gifContractedBlock.gif
/**//**//**///////////////////////////////////////////////////////////////////////
//Construction/Destruction
ExpandedBlockStart.gifContractedBlock.gif
/**//**//**///////////////////////////////////////////////////////////////////////
template<typenameT>
CAVLTree
<T>::CAVLTree()
ExpandedBlockStart.gifContractedBlock.gif
{
this->root=NULL;
this->size=0;
}

template
<typenameT>
CAVLTree
<T>::CAVLTree(constCAVLTree<T>&tree)
ExpandedBlockStart.gifContractedBlock.gif
{
root
=this->CopyTree(tree.root);
this->size=tree.size;
}

template
<typenameT>
CAVLTree
<T>::~CAVLTree()
ExpandedBlockStart.gifContractedBlock.gif
{
this->ClearTree();
}

template
<typenameT>
CAVLTree
<T>&CAVLTree<T>::operator=(constCAVLTree<T>&rhs)
ExpandedBlockStart.gifContractedBlock.gif
{
if(this==&rhs)
return*this;
this->ClearTree();
root
=this->CopyTree(rhs.root);
size
=rhs.size;
return*this;
}

template
<typenameT>
CAVLTreeNode
<T>*CAVLTree<T>::GetAVLTreeNode(constT&item,CAVLTreeNode<T>*lptr,CAVLTreeNode<T>*rptr)
ExpandedBlockStart.gifContractedBlock.gif
{
CAVLTreeNode
<T>*p;
p
=newCAVLTreeNode<T>(item,lptr,rptr);
if(p==NULL)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
cerr
<<"分配内存失败!"<<endl;
exit(
1);
}

returnp;
}

template
<typenameT>
CAVLTreeNode
<T>*CAVLTree<T>::FindMin()const
ExpandedBlockStart.gifContractedBlock.gif
{
CAVLTreeNode
<T>*t=root;
while(t->left!=NULL)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
t
=t->left;
}

returnt;
}

template
<typenameT>
CAVLTreeNode
<T>*CAVLTree<T>::FindMax()const
ExpandedBlockStart.gifContractedBlock.gif
{
CAVLTreeNode
<T>*t=root;
while(t->right!=NULL)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
t
=t->right;
}

returnt;
}

template
<typenameT>
boolCAVLTree<T>::Contains(constT&item)
ExpandedBlockStart.gifContractedBlock.gif
{
CAVLTreeNode
<T>*p;
return(this->FindNode(item,p)!=NULL);
}


template
<typenameT>
CAVLTreeNode
<T>*CAVLTree<T>::CopyTree(CAVLTreeNode<T>*t)
ExpandedBlockStart.gifContractedBlock.gif
{
CAVLTreeNode
<T>*newnode,*newlptr,*newrptr;
if(t==NULL)
returnNULL;
if(t->Left()!=NULL)
newlptr
=CopyTree(t->Left());
else
newlptr
=NULL;
if(t->Right()!=NULL)
newrptr
=CopyTree(t->Right());
else
newrptr
=NULL;
newnode
=this->GetAVLTreeNode(t->data,newlptr,newrptr);
returnnewnode;
}

template
<typenameT>
voidCAVLTree<T>::FreeTreeNode(CAVLTreeNode<T>*p)
ExpandedBlockStart.gifContractedBlock.gif
{
deletep;
p
=NULL;
}

template
<typenameT>
voidCAVLTree<T>::DeleteTree(CAVLTreeNode<T>*t)
ExpandedBlockStart.gifContractedBlock.gif
{
if(t!=NULL)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
DeleteTree(t
->Left());
DeleteTree(t
->Right());
FreeTreeNode(t);
}

}

template
<typenameT>
voidCAVLTree<T>::ClearTree()
ExpandedBlockStart.gifContractedBlock.gif
{
DeleteTree(root);
root
=NULL;
}

template
<typenameT>
CAVLTreeNode
<T>*CAVLTree<T>::FindNode(constT&item,CAVLTreeNode<T>*&parent)const
ExpandedBlockStart.gifContractedBlock.gif
{
CAVLTreeNode
<T>*t=root;
parent
=NULL;
while(t!=NULL)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
if(item==t->data)
break;
else
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
parent
=t;
if(item<t->data)
t
=t->Left();
else
t
=t->Right();
}

}

returnt;
}

template
<typenameT>
voidCAVLTree<T>::Insert(constT&item)
ExpandedBlockStart.gifContractedBlock.gif
{
CAVLTreeNode
<T>*t=root,*parent=NULL,*newnode;
intreviseBalanceFactor=0;
newnode
=this->GetAVLTreeNode(item);
this->AVLInsert(t,newnode,reviseBalanceFactor);
root
=t;
size
++;
}

template
<typenameT>
voidCAVLTree<T>::AVLInsert(CAVLTreeNode<T>*&tree,CAVLTreeNode<T>*newnode,int&reviseBalanceFactor)
ExpandedBlockStart.gifContractedBlock.gif
{

intrebalanceCurrNode;
if(tree==NULL)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
tree
=newnode;
tree
->balanceFactor=BALANCE;
reviseBalanceFactor
=1;
}

elseif(newnode->data<tree->data)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
this->AVLInsert(tree->Left(),newnode,rebalanceCurrNode);
if(rebalanceCurrNode)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
if(tree->balanceFactor==LEFTHEAVY)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
this->UpdateLeftTree(tree,reviseBalanceFactor);
}

elseif(tree->balanceFactor==BALANCE)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
tree
->balanceFactor=LEFTHEAVY;
reviseBalanceFactor
=1;
}

else
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
tree
->balanceFactor=BALANCE;
reviseBalanceFactor
=0;
}

}

}

else
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
this->AVLInsert(tree->Right(),newnode,rebalanceCurrNode);
if(rebalanceCurrNode)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
if(tree->balanceFactor==LEFTHEAVY)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
tree
->balanceFactor=BALANCE;
reviseBalanceFactor
=0;
}

elseif(tree->balanceFactor==BALANCE)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
tree
->balanceFactor=RIGHTHEAVY;
reviseBalanceFactor
=1;
}

else
this->UpdateRightTree(tree,reviseBalanceFactor);
}

else
reviseBalanceFactor
=0;
}

}


template
<typenameT>
voidCAVLTree<T>::PrintTree()
ExpandedBlockStart.gifContractedBlock.gif
{
stack
<CAVLTreeNode<T>*>s;
CAVLTreeNode
<T>*p=root;
while(p!=NULL||!s.empty())
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
while(p!=NULL)//遍历左子树
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
cout
<<p->data<<endl;
s.push(p);
p
=p->Left();
}
//endwhile

if(!s.empty())
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
p
=s.top();
s.pop();
p
=p->Right();//通过下一次循环实现右子树遍历
}
//endif
}

}

template
<typenameT>
voidCAVLTree<T>::UpdateLeftTree(CAVLTreeNode<T>*&tree,int&reviseBalanceFactor)
ExpandedBlockStart.gifContractedBlock.gif
{
CAVLTreeNode
<T>*lc;
lc
=tree->Left();
if(lc->balanceFactor==LEFTHEAVY)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
this->SingleRotateRight(tree);
reviseBalanceFactor
=0;
}

elseif(lc->balanceFactor==RIGHTHEAVY)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
this->DoubleRotateRight(tree);
reviseBalanceFactor
=0;
}

}

template
<typenameT>
voidCAVLTree<T>::SingleRotateRight(CAVLTreeNode<T>*&p)
ExpandedBlockStart.gifContractedBlock.gif
{
CAVLTreeNode
<T>*lc;
lc
=p->Left();
p
->balanceFactor=BALANCE;
lc
->balanceFactor=BALANCE;
p
->left=lc->Right();
lc
->right=p;
p
=lc;
}

template
<typenameT>
voidCAVLTree<T>::DoubleRotateRight(CAVLTreeNode<T>*&p)
ExpandedBlockStart.gifContractedBlock.gif
{
CAVLTreeNode
<T>*lc,*np;
lc
=p->Left();
np
=lc->Right();
if(np->balanceFactor==RIGHTHEAVY)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
p
->balanceFactor=BALANCE;
lc
->balanceFactor=RIGHTHEAVY;
}

elseif(np->balanceFactor==BALANCE)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
p
->balanceFactor=BALANCE;
lc
->balanceFactor=BALANCE;
}

else
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
p
->balanceFactor=RIGHTHEAVY;
lc
->balanceFactor=BALANCE;
}

np
->balanceFactor=BALANCE;
lc
->right=np->Left();
np
->left=lc;
p
->left=np->Right();
np
->right=p;
p
=np;
}

template
<typenameT>
voidCAVLTree<T>::SingleRotateLeft(CAVLTreeNode<T>*&p)
ExpandedBlockStart.gifContractedBlock.gif
{
CAVLTreeNode
<T>*rc=p->right;

p
->balanceFactor=BALANCE;
rc
->balanceFactor=BALANCE;

p
->right=rc->left;
rc
->left=p;
p
=rc;

}

template
<typenameT>
voidCAVLTree<T>::DoubleRotateLeft(CAVLTreeNode<T>*&p)
ExpandedBlockStart.gifContractedBlock.gif
{
CAVLTreeNode
<T>*rc,*np;

rc
=p->right;
np
=rc->left;
if(np->balanceFactor==LEFTHEAVY)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
p
->balanceFactor=BALANCE;
rc
->balanceFactor=LEFTHEAVY;
}

elseif(np->balanceFactor==BALANCE)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
p
->balanceFactor=BALANCE;
rc
->balanceFactor=BALANCE;
}

else
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
p
->balanceFactor=LEFTHEAVY;
rc
->balanceFactor=BALANCE;
}

np
->balanceFactor=BALANCE;
rc
->left=np->right;
np
->right=rc;
p
->right=np->left;
np
->left=p;
p
=np;
}

template
<typenameT>
voidCAVLTree<T>::UpdateRightTree(CAVLTreeNode<T>*&tree,int&reviseBalanceFactor)
ExpandedBlockStart.gifContractedBlock.gif
{
CAVLTreeNode
<T>*rc=tree->right;

if(rc->balanceFactor==RIGHTHEAVY)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
SingleRotateLeft(tree);
reviseBalanceFactor
=false;
}

elseif(rc->balanceFactor==LEFTHEAVY)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
DoubleRotateLeft(tree);
reviseBalanceFactor
=false;
}

}

测试代码

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->#include"BinSTree.cpp"
#include
<iostream>
usingnamespacestd;

CAVLTree
<int>*MakeSampleTree()
ExpandedBlockStart.gifContractedBlock.gif
{//示例AVL树
CAVLTree<int>*tree1=newCAVLTree<int>();
inta=5;
tree1
->Insert(a);
tree1
->Insert(30);
tree1
->Insert(65);
tree1
->Insert(25);
tree1
->Insert(35);
tree1
->Insert(50);
tree1
->Insert(10);
tree1
->Insert(28);
tree1
->Insert(26);
tree1
->Insert(33);
returntree1;
}


intmain(intargc,char*argv[])
ExpandedBlockStart.gifContractedBlock.gif
{
CAVLTree
<int>*tree1=MakeSampleTree();
tree1
->PrintTree();

cout
<<tree1->Contains(40)<<endl;
CAVLTreeNode
<int>*p=tree1->FindMin();
cout
<<p->data<<endl;
system(
"pause");
return0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值