AVLTree 代码优化

来源:互联网 发布:ppt数据分析图表模板 编辑:程序博客网 时间:2024/05/21 14:09
</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;}


0 0
原创粉丝点击