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


#include 
< stdlib.h >

template
< typename T >
class  CAVLTree;

template
< typename T >
class  CAVLTreeNode
ExpandedBlockStart.gifContractedBlock.gif
{
public:
    CAVLTreeNode(
const T& item,CAVLTreeNode<T>* lptr = NULL,CAVLTreeNode<T>* rptr = NULL,int balfac=0):data(item),left(lptr),right(rptr),balanceFactor(balfac)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
    }

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

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

    
int GetBalanceFactor()const
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
return this->balanceFactor;
    }

    friend 
class CAVLTree<T>;
public:
    T data;
//数据
private:
    CAVLTreeNode
<T>* left;//左子树
    CAVLTreeNode<T>* right;//右子树
    int balanceFactor;//平衡因子
    CAVLTreeNode<T>* & Left(void)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
return left;
    }

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


}
;

const   int  LEFTHEAVY  =   - 1 ;
const   int  BALANCE  =   0 ;
const   int  RIGHTHEAVY  =   1 ;

template
< typename T >
class  CAVLTree
ExpandedBlockStart.gifContractedBlock.gif
{
public:
    CAVLTree(
void);
    CAVLTree(
const CAVLTree<T>& tree);
    CAVLTree
& operator = (const CAVLTree& rhs);
    
void Insert(const T& item);
    
void ClearTree();//清空树
    bool Contains(const T& item);//是否包含数据
    CAVLTreeNode<T>* FindNode(const T& item,CAVLTreeNode<T>* &parent)const;//寻找节点
    CAVLTreeNode<T>* FindMin()const;//找最小值
    CAVLTreeNode<T>* FindMax()const;//找最大值
    void PrintTree();//前序遍历树(非递归)
    virtual ~CAVLTree(void);

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

    
//旋转
    void SingleRotateLeft(CAVLTreeNode<T> * &p);
    
void SingleRotateRight(CAVLTreeNode<T> *&p);
    
void DoubleRotateLeft(CAVLTreeNode<T> *&p);
    
void DoubleRotateRight(CAVLTreeNode<T> *&p);

    
void UpdateLeftTree(CAVLTreeNode<T>* &tree,int &reviseBalanceFactor);
    
void UpdateRightTree(CAVLTreeNode<T>* &tree,int &reviseBalanceFactor);
    
void AVLInsert(CAVLTreeNode<T> * &tree,CAVLTreeNode<T> *newnode,int &reviseBalanceFactor);

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

 

ContractedBlock.gif ExpandedBlockStart.gif 平衡二叉树实现代码
#include "BinSTree.h"
#include 
<iostream>
#include 
<stack>
using namespace std;

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

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

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

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

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

    
return p;
}

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

    
return t;
}

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

    
return t;
}

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


template
<typename T>
CAVLTreeNode
<T>* CAVLTree<T>::CopyTree(CAVLTreeNode<T>* t)
ExpandedBlockStart.gifContractedBlock.gif
{
    CAVLTreeNode
<T> *newnode,*newlptr,*newrptr;
    
if(t==NULL)
        
return NULL;
    
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);
    
return newnode;
}

template
<typename T>
void CAVLTree<T>::FreeTreeNode(CAVLTreeNode<T>* p)
ExpandedBlockStart.gifContractedBlock.gif
{
    delete p;
    p 
= NULL;
}

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

}

template
<typename T>
void CAVLTree<T>::ClearTree()
ExpandedBlockStart.gifContractedBlock.gif
{
    DeleteTree(root);
    root 
= NULL;
}

template
<typename T>
CAVLTreeNode
<T>* CAVLTree<T>::FindNode(const T& item,CAVLTreeNode<T>* &parent)const
ExpandedBlockStart.gifContractedBlock.gif
{
    CAVLTreeNode
<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();
        }

    }

    
return t;
}

template
<typename T>
void CAVLTree<T>::Insert(const T& item)
ExpandedBlockStart.gifContractedBlock.gif
{
    CAVLTreeNode
<T>* t = root,*parent = NULL,*newnode;
    
int reviseBalanceFactor = 0;
    newnode 
= this->GetAVLTreeNode(item);
    
this->AVLInsert(t,newnode,reviseBalanceFactor);
    root 
= t;
    size
++;
}

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

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

    
else if(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);
            }

            
else if (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;
            }

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

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

        
else
            reviseBalanceFactor 
= 0;
    }

}


template
<typename T>
void CAVLTree<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
<typename T>
void CAVLTree<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;
    }

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

}

template
<typename T>
void CAVLTree<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
<typename T>
void CAVLTree<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;
    }

    
else if (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
<typename T>
void CAVLTree<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
<typename T>
void CAVLTree<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;
    }

    
else if (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
<typename T>
void CAVLTree<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;
    }

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

测试代码

#include  " BinSTree.cpp "
#include 
< iostream >
using   namespace  std;

CAVLTree
< int >*  MakeSampleTree()
ExpandedBlockStart.gifContractedBlock.gif
{//示例AVL树
    CAVLTree<int> *tree1 = new CAVLTree<int>();
    
int a = 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);
    
return tree1;
}


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

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



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值