</pre><pre name="code" class="html">/**********************************************************************
* Title: A Plain Implementation of AVLTree
*
* Motivation: Like the Plain Style Codes
*
* Author: stinkaroo
*
* Email: 190690276@qq.com
*
* Date: 2016-5-20
*
* Reference: http://www.cppblog.com/cxiaojia/
* archive/2012/08/20/187776.html
*
* Other tips: Since the original article is written by Chinese,
* so I mixed English and Chinese in my codes.
**********************************************************************/
#include <stdio.h>
#include <iostream>
using namespace std;
//外部提供的访问数据的函数
void visit(int data);
/**********************Node of AVLTree******************************/
template<class T>
class TreeNode
{
public:
TreeNode(): leftChild_(NULL), rightChild_(NULL), height_(1){}
public:
TreeNode *leftChild_; //指向左儿子的地址
TreeNode *rightChild_; //指向右儿子的地址
T data_; //数据元素
int height_; //以此节点为根的树的高度
};
/**********************Node of AVLTree******************************/
/**********************Structure of AVLTree******************************/
template<class T>
class AVLTree
{
public:
AVLTree():root(NULL){}
//查找, 未找到返回空指针
TreeNode<T>* Search(T x);
//插入值, 插入成功返回0值, 插入失败返回-1
int Insert(T x);
//删除值, 删除成功返回0值, 删除失败返回-1
int Delete(T x);
//遍历平衡二叉树
void Traversal(void (*visit)(T));
private:
TreeNode<T>* Search(TreeNode<T>* node, T x); //查找,仅声明,未实现
int Insert(TreeNode<T> *&node, T x); //插入
int Delete(TreeNode<T> *&node, T x); //删除
void InOrderTraversal(TreeNode<T> *node, void(*visit)(T)); //中序遍历
//通过旋转操作让树重新平衡, type == 0 表示可能左树过高,
// type == 1 表示可能右树过高
void ReBalance(TreeNode<T> *&node, int type);
//旋转函数以实际旋转方向命名
void RotateRight(TreeNode<T> *&node); //左左情形, 树向右旋转(顺时针方向)
void RotateLeft(TreeNode<T> *&node); //右右情形, 树向左旋转(逆时针方向)
void RotateLR(TreeNode<T> *&node); //左右情形, 先向左旋转, 再向右旋转
void RotateRL(TreeNode<T> *&node); //右左情形, 先向右旋转, 再向左旋转
int Height(TreeNode<T> *node);//求树的高度
int Bigger(int a, int b);//求较大值
private:
TreeNode<T> *root;//根节点
};
/**********************Structure of AVLTree******************************/
/**********************Public Interface of AVLTree***********************/
//NO.1 查找结点
template<class T>
TreeNode<T>* AVLTree<T>::Search(T x)
{
return Search(root, x);
}
//NO.2 插入结点
template<class T>
int AVLTree<T>::Insert(T x)
{
Insert(root, x);
}
//NO.3 删除结点
template<class T>
int AVLTree<T>::Delete(T x)
{
Delete(root, x);
}
//NO.4 遍历平衡二叉树
template<class T>
void AVLTree<T>::Traversal(void(*visit)(T))
{
InOrderTraversal(root, visit);
}
/**********************Public Interface of AVLTree***********************/
/**********************Internal Private Function of AVLTree**************/
//NO.5 查找结点
template<class T>
TreeNode<T>* AVLTree<T>::Search(TreeNode<T> *node, T x)
{
if(node == NULL){ //未找到目标结点
return NULL;
}
if(x == node->data_){
return node;
}
else if(x < node->data_){
return Search(node->leftChild_, x);
}
else{
return Search(node->rightChild_, x);
}
}
//NO.6 插入结点
template<class T>
int AVLTree<T>::Insert(TreeNode<T> *&node, T x)
{
if(node == NULL){ //如果节点为空,就在此节点处加入x信息
node = new TreeNode<T>();
node->data_ = x;
return 0;
}
int result = 0;
if(x < node->data_){ //如果x小于节点的值,就继续在节点的左子树中插入x
result = Insert(node->leftChild_, x);
ReBalance(node, 0);
}
else if(x > node->data_){ //如果x大于节点的值,就继续在节点的右子树中插入x
result = Insert(node->rightChild_, x);
ReBalance(node, 1);
}
//调整结点高度值
node->height_ = Bigger(Height(node->leftChild_), Height(node->rightChild_));
return result;
}
//NO.7 删除结点
template<class T>
int AVLTree<T>::Delete(TreeNode<T> *&node, T x)
{
if(node == NULL){ //没有找到值是x的节点
return -1;
}
int result = 0;
if(x < node->data_){
result = Delete(node->leftChild_, x);//如果x小于节点的值,就继续在节点的左子树中删除x
ReBalance(node, 1);
}
else if(x > node->data_){
result = Delete(node->rightChild_, x);//如果x大于节点的值,就继续在节点的右子树中删除x
ReBalance(node, 0);
}
else{ //如果相等,此节点就是要删除的节点
result = 0;
if(node->leftChild_ && node->rightChild_){ //此节点有两个儿子
TreeNode<T>* temp = node->rightChild_; //temp指向节点的右儿子
while(temp->leftChild_ != NULL){
temp = temp->leftChild_;//找到右子树中值最小的节点
}
//把右子树中最小节点的值赋值给本节点
node->data_ = temp->data_;
Delete(node->rightChild_, temp->data_);//删除右子树中最小值的节点
ReBalance(node, 0);
}
else//此节点有1个或0个儿子
{
TreeNode<T> *temp = node;
if(node->leftChild_ == NULL){ //有右儿子或者没有儿子
node = node->rightChild_;
}
else if(node->rightChild_== NULL){ //有左儿子
node = node->leftChild_;
}
delete(temp);
temp = NULL;
}
}
node->height_ = Bigger(Height(node->leftChild_), Height(node->rightChild_)) + 1;
return 0;
}
//NO.8 中序遍历树
template<class T>
void AVLTree<T>::InOrderTraversal(TreeNode<T>* node, void (*vist)(T))
{
if(node == NULL){
return;
}
InOrderTraversal(node->leftChild_, visit); //先遍历左子树
vist(node->data_); //访问数据
InOrderTraversal(node->rightChild_, visit); //再遍历右子树
}
//NO.9 重新平衡树
template<class T>
void AVLTree<T>::ReBalance(TreeNode<T> *&node, int type)
{
if(type == 0){ //可能左树过高, 作相应调整
if(2 == Height(node->leftChild_) - Height(node->rightChild_)){
if(Height(node->leftChild_->leftChild_)
> Height(node->leftChild_->rightChild_)){
RotateRight(node);
}
else{
RotateLR(node);
}
}
}
else if(type == 1){ //可能右树过高, 作相应调整
if(2 == Height(node->rightChild_) - Height(node->leftChild_)){
if(Height(node->rightChild_->rightChild_)
> Height(node->rightChild_->leftChild_)){
RotateLeft(node);
}
else{
RotateRL(node);
}
}//
}
}
//NO.10 左左情况下的旋转
template<class T>
void AVLTree<T>::RotateRight(TreeNode<T> *&node)
{
TreeNode<T> *node2;
node2 = node->leftChild_;
node->leftChild_ = node2->rightChild_;
node2->rightChild_ = node;
node->height_ = Bigger(Height(node->leftChild_), Height(node->rightChild_)) + 1;
node2->height_ = Bigger(Height(node2->leftChild_), node->height_) + 1;
}
//NO.11 右右情况下的旋转
template<class T>
void AVLTree<T>::RotateLeft(TreeNode<T>* &node)
{
TreeNode<T> *node2;
node2 = node->rightChild_;
node->rightChild_ = node2->leftChild_;
node2->leftChild_ = node;
node->height_ = Bigger(Height(node->leftChild_), Height(node->rightChild_)) + 1;
node2->height_ = Bigger(Height(node2->rightChild_), node->height_) + 1;
}
//NO.12 左右情况的旋转
template<class T>
void AVLTree<T>::RotateLR(TreeNode<T> *&node)
{
RotateLeft(node->leftChild_);
RotateRight(node);
}
//NO.13 右左情况的旋转
template<class T>
void AVLTree<T>::RotateRL(TreeNode<T> *&node)
{
RotateRight(node->rightChild_);
RotateLeft(node);
}
//NO.14 计算以节点为根的树的高度
template<class T>
int AVLTree<T>::Height(TreeNode<T> *node)
{
if(node != NULL)
return node->height_;
return 0;
}
//NO.15 求较大值
template<class T>
int AVLTree<T>::Bigger(int a, int b)
{
return a > b ? a : b;
}
/**********************Internal Private Function of AVLTree**************/
//访问数据函数的实现
void visit(int data)
{
cout << data << " ";
}
//简单验证程序
int main()
{
AVLTree<int> tree;
const int testSize = 24;
for(int i = 0; i < testSize; i++){
tree.Insert(i);
}
for(int i = 0; i < testSize; i += 2){
tree.Delete(i);
}
tree.Traversal(visit);
TreeNode<int> *a = tree.Search(15);
cout << "\na->data_ == " << a->data_ << '\n';
return 0;
}
AVLTree 代码优化
最新推荐文章于 2026-04-26 15:05:04 发布

2000

被折叠的 条评论
为什么被折叠?



