AVL 二叉平衡树 C++ 实现

头文件

#ifndef DEBUG_LRN_AVL_H
#define DEBUG_LRN_AVL_H

#include <iostream>

using namespace std;

template <class T>

class AVLTreeNode {
public:
    T key;
    int height; //
    AVLTreeNode* left;
    AVLTreeNode* right;
    AVLTreeNode(T value, AVLTreeNode *l, AVLTreeNode *r):
                 key(value), height(0),left(l),right(r) {}
};




template <class T>
class AVLTree {
private:
    AVLTreeNode<T> *mRoot;    // 根结点

public:
    AVLTree();
    ~AVLTree();

    // 获取树的高度
    int get_height();
    // 获取树的高度
    int max(int a, int b);

    // 前序遍历"AVL树"
    void preOrder();
    // 中序遍历"AVL树"
    void inOrder();
    // 后序遍历"AVL树"
    void postOrder();

    // (递归实现)查找"AVL树"中键值为key的节点
    AVLTreeNode<T>* search(T key);
    // (非递归实现)查找"AVL树"中键值为key的节点
    AVLTreeNode<T>* iterativeSearch(T key);

    // 查找最小结点:返回最小结点的键值。
    T minimum();
    // 查找最大结点:返回最大结点的键值。
    T maximum();

    // 将结点(key为节点键值)插入到AVL树中
    void insert(T key);

    // 删除结点(key为节点键值)
    void remove(T key);

    // 销毁AVL树
    void destroy();

    // 打印AVL树
    void print();
private:
    // 获取树的高度
    int get_height(AVLTreeNode<T>* tree) ;

    // 前序遍历"AVL树"
    void preOrder(AVLTreeNode<T>* tree) const;
    // 中序遍历"AVL树"
    void inOrder(AVLTreeNode<T>* tree) const;
    // 后序遍历"AVL树"
    void postOrder(AVLTreeNode<T>* tree) const;

    // (递归实现)查找"AVL树x"中键值为key的节点
    AVLTreeNode<T>* search(AVLTreeNode<T>* x, T key) const;
    // (非递归实现)查找"AVL树x"中键值为key的节点
    AVLTreeNode<T>* iterativeSearch(AVLTreeNode<T>* x, T key) const;

    // 查找最小结点:返回tree为根结点的AVL树的最小结点。
    AVLTreeNode<T>* minimum(AVLTreeNode<T>* tree);
    // 查找最大结点:返回tree为根结点的AVL树的最大结点。
    AVLTreeNode<T>* maximum(AVLTreeNode<T>* tree);

    // LL:左左对应的情况(左单旋转)。
    AVLTreeNode<T>* leftLeftRotation(AVLTreeNode<T>* k2);

    // RR:右右对应的情况(右单旋转)。
    AVLTreeNode<T>* rightRightRotation(AVLTreeNode<T>* k1);

    // LR:左右对应的情况(左双旋转)。
    AVLTreeNode<T>* leftRightRotation(AVLTreeNode<T>* k3);

    // RL:右左对应的情况(右双旋转)。
    AVLTreeNode<T>* rightLeftRotation(AVLTreeNode<T>* k1);

    // 将结点(z)插入到AVL树(tree)中
    AVLTreeNode<T>* insert(AVLTreeNode<T>* &tree, T key);

    // 删除AVL树(tree)中的结点(z),并返回被删除的结点
    AVLTreeNode<T>* remove(AVLTreeNode<T>* &tree, AVLTreeNode<T>* z);

    // 销毁AVL树
    void destroy(AVLTreeNode<T>* &tree);

    // 打印AVL树
    void print(AVLTreeNode<T>* tree, T key, int direction);
};


int test_avl_tree();

#endif //DEBUG_LRN_AVL_H

源文件

#include <vector>
#include <iomanip>
#include "AVLTreeNode.h"

template <class T>
AVLTree<T>::AVLTree():mRoot(nullptr){}

template <class T>
AVLTree<T>::~AVLTree() {
    destroy(mRoot);
}

/*
 * 获取树的高度
 */
template <class T>
int AVLTree<T>::get_height(AVLTreeNode<T>* tree)
{
    if (tree != nullptr)
        return tree->height;

    return 0;
}

template <class T>
int AVLTree<T>::get_height()
{
    return get_height(mRoot);
}

/*
 * 比较两个值的大小
 */
template <class T>
int AVLTree<T>::max(int a, int b)
{
    return a>b ? a : b;
}


/*
 * LL:左左对应的情况(左单旋转)。
 *
 * 返回值:旋转后的根节点
 */
template <class T>
AVLTreeNode<T>* AVLTree<T>::leftLeftRotation(AVLTreeNode<T>* k2)
{
    AVLTreeNode<T>* k1;

    k1 = k2->left;
    k2->left = k1->right;
    k1->right = k2;

    k2->height = max( get_height(k2->left), get_height(k2->right)) + 1;
    k1->height = max( get_height(k1->left), k2->height) + 1;

    return k1;
}

/*
 * RR:右右对应的情况(右单旋转)。
 *
 * 返回值:旋转后的根节点
 */
template <class T>
AVLTreeNode<T>* AVLTree<T>::rightRightRotation(AVLTreeNode<T>* k1)
{
    AVLTreeNode<T>* k2;

    k2 = k1->right;
    k1->right = k2->left;
    k2->left = k1;

    k1->height = max( get_height(k1->left), get_height(k1->right)) + 1;
    k2->height = max( get_height(k2->right), k1->height) + 1;

    return k2;
}

/*
 * LR:左右对应的情况(左双旋转)。
 *
 * 返回值:旋转后的根节点
 */
template <class T>
AVLTreeNode<T>* AVLTree<T>::leftRightRotation(AVLTreeNode<T>* k3)
{
    k3->left = rightRightRotation(k3->left);

    return leftLeftRotation(k3);
}


/*
 * RL:右左对应的情况(右双旋转)。
 *
 * 返回值:旋转后的根节点
 */
template <class T>
AVLTreeNode<T>* AVLTree<T>::rightLeftRotation(AVLTreeNode<T>* k1)
{
    k1->right = leftLeftRotation(k1->right);

    return rightRightRotation(k1);
}

/*
 * 将结点插入到AVL树中,并返回根节点
 *
 * 参数说明:
 *     tree AVL树的根结点
 *     key 插入的结点的键值
 * 返回值:
 *     根节点
 */
template <class T>
AVLTreeNode<T>* AVLTree<T>::insert(AVLTreeNode<T>* &tree, T key)
{
    if (tree == nullptr)
    {
        // 新建节点
        tree = new AVLTreeNode<T>(key, nullptr, nullptr);
    }
    else if (key < tree->key) // 应该将key插入到"tree的左子树"的情况
    {
        tree->left = insert(tree->left, key);
        // 插入节点后,若AVL树失去平衡,则进行相应的调节。
        if (get_height(tree->left) - get_height(tree->right) == 2)
        {
            if (key < tree->left->key)
                tree = leftLeftRotation(tree);
            else
                tree = leftRightRotation(tree);
        }
    }
    else if (key > tree->key) // 应该将key插入到"tree的右子树"的情况
    {
        tree->right = insert(tree->right, key);
        // 插入节点后,若AVL树失去平衡,则进行相应的调节。
        if (get_height(tree->right) - get_height(tree->left) == 2)
        {
            if (key > tree->right->key)
                tree = rightRightRotation(tree);
            else
                tree = rightLeftRotation(tree);
        }
    }
    else //key == tree->key)
    {
        cout << "添加失败:不允许添加相同的节点!" << endl;
    }

    tree->height = max( get_height(tree->left), get_height(tree->right)) + 1;

    return tree;
}

template <class T>
void AVLTree<T>::insert(T key)
{
    insert(mRoot, key);
}


/* 
 * 删除结点(z),返回根节点
 *
 * 参数说明:
 *     tree AVL树的根结点
 *     z 待删除的结点
 * 返回值:
 *     根节点
 */
template <class T>
AVLTreeNode<T>* AVLTree<T>::remove(AVLTreeNode<T>* &tree, AVLTreeNode<T>* z)
{
    // 根为空 或者 没有要删除的节点,直接返回nullptr。
    if (tree == nullptr || z == nullptr)
        return nullptr;

    if (z->key < tree->key)        // 待删除的节点在"tree的左子树"中
    {
        tree->left = remove(tree->left, z);
        // 删除节点后,若AVL树失去平衡,则进行相应的调节。
        if (get_height(tree->right) - get_height(tree->left) == 2)
        {
            AVLTreeNode<T> *r =  tree->right;
            if (get_height(r->left) > get_height(r->right))
                tree = rightLeftRotation(tree);
            else
                tree = rightRightRotation(tree);
        }
    }
    else if (z->key > tree->key)// 待删除的节点在"tree的右子树"中
    {
        tree->right = remove(tree->right, z);
        // 删除节点后,若AVL树失去平衡,则进行相应的调节。
        if (get_height(tree->left) - get_height(tree->right) == 2)
        {
            AVLTreeNode<T> *l =  tree->left;
            if (get_height(l->right) > get_height(l->left))
                tree = leftRightRotation(tree);
            else
                tree = leftLeftRotation(tree);
        }
    }
    else    // tree是对应要删除的节点。
    {
        // tree的左右孩子都非空
        if ((tree->left != nullptr) && (tree->right != nullptr))
        {
            if (get_height(tree->left) > get_height(tree->right))
            {
                // 如果tree的左子树比右子树高;
                // 则(01)找出tree的左子树中的最大节点
                //   (02)将该最大节点的值赋值给tree。
                //   (03)删除该最大节点。
                // 这类似于用"tree的左子树中最大节点"做"tree"的替身;
                // 采用这种方式的好处是:删除"tree的左子树中最大节点"之后,AVL树仍然是平衡的。
                AVLTreeNode<T>* max = maximum(tree->left);
                tree->key = max->key;
                tree->left = remove(tree->left, max);
            }
            else
            {
                // 如果tree的左子树不比右子树高(即它们相等,或右子树比左子树高1)
                // 则(01)找出tree的右子树中的最小节点
                //   (02)将该最小节点的值赋值给tree。
                //   (03)删除该最小节点。
                // 这类似于用"tree的右子树中最小节点"做"tree"的替身;
                // 采用这种方式的好处是:删除"tree的右子树中最小节点"之后,AVL树仍然是平衡的。
                AVLTreeNode<T>* min = maximum(tree->right);
                tree->key = min->key;
                tree->right = remove(tree->right, min);
            }
        }
        else
        {
            AVLTreeNode<T>* tmp = tree;
            tree = (tree->left != nullptr) ? tree->left : tree->right;
            delete tmp;
        }
    }

    return tree;
}

template <class T>
void AVLTree<T>::remove(T key)
{
    AVLTreeNode<T>* z;

    if ((z = search(mRoot, key)) != nullptr)
        mRoot = remove(mRoot, z);
}

template <class T>
void AVLTree<T>::preOrder(AVLTreeNode<T> *tree) const {
    if (tree != nullptr){
        cout << tree->key << ", ";
        preOrder(tree->left);
        preOrder(tree->right);
    }
}


template <class T>
void AVLTree<T>::preOrder(){
    return preOrder(mRoot);
}


template <class T>
void AVLTree<T>::inOrder(AVLTreeNode<T> *tree) const {
    if (tree != nullptr){
        inOrder(tree->left);
        cout << tree->key << ", ";
        inOrder(tree->right);
    }
}


template <class T>
void AVLTree<T>::inOrder(){
    return inOrder(mRoot);
}

template <class T>
void AVLTree<T>::postOrder(AVLTreeNode<T> *tree) const {
    if (tree != nullptr){
        postOrder(tree->left);
        postOrder(tree->right);
        cout << tree->key << ", ";
    }
}


template <class T>
void AVLTree<T>::postOrder(){
    return postOrder(mRoot);
}

template <class T>
AVLTreeNode<T>* AVLTree<T>::minimum(AVLTreeNode<T> *tree) {
    if(tree == nullptr){
        return nullptr;
    }
    while(tree->left != nullptr){
        tree = tree->left;
    }
    return tree;
}

template <class T>
T AVLTree<T>::minimum() {
    return minimum(mRoot)->key;
}

template <class T>
AVLTreeNode<T>* AVLTree<T>::maximum(AVLTreeNode<T> *tree) {
    if(tree == nullptr){
        return nullptr;
    }
    while(tree->left != nullptr){
        tree = tree->left;
    }
    return tree;
}

template <class T>
T AVLTree<T>::maximum() {
    return minimum(mRoot)->key;
}

//template <class T>
//TreeNode* tree_search(TreeNode* x, int k)
//{
//    if(x == nullptr || k == x->key)
//        return x;
//    if(k < x->key)
//        return tree_search(x->left, k);
//    else return tree_search(x->right, k);
//}

template <class T>
AVLTreeNode<T>* AVLTree<T>::search(AVLTreeNode<T>* x, T key) const{
    if( x == nullptr || key == x->key){
        return x;
    }
    if(key < x->key){
        return search(x->left, key);
    }
    else{
        return search(x->right, key);
    }
}


template <class T>
AVLTreeNode<T>* AVLTree<T>::search(T key){
    return search(mRoot, key);
}

template <class T>
AVLTreeNode<T>* AVLTree<T>::iterativeSearch(AVLTreeNode<T> *x, T key) const {
    while( x != nullptr && x->key != key){
        if(key < x->key){
            x = x->left;
        }
        else{
            x = x->right;
        }
    }
    return x;
}

template <class T>
AVLTreeNode<T>* AVLTree<T>::iterativeSearch(T key) {
    return iterativeSearch(mRoot, key);
}


template <class T> void AVLTree<T>::destroy(AVLTreeNode<T>* &tree)
{
     if (tree == nullptr)
         return ;

     if (tree->left != nullptr)
         destroy(tree->left);
     if (tree->right != nullptr)
         destroy(tree->right);

     delete tree;
}

template <class T>
void AVLTree<T>::destroy()
{
     destroy(mRoot);
}


template <class T>
void AVLTree<T>::print(AVLTreeNode<T>* tree, T key, int direction){
    if(tree != nullptr){
        if(direction == 0){
            cout << setw(2) << tree->key << " is root" << endl;
        }
        else{
            cout << setw(2) << tree->key << " is " << setw(2) << key << "'s "  << setw(12) << (direction==1?"right child" : "left child") << endl;
        }
        print(tree->left, tree->key, -1);
        print(tree->right, tree->key, 1);
    }
}

template <class T>
void AVLTree<T>::print()
{
    if(mRoot != nullptr){
        print(mRoot, mRoot->key, 0);
    }
}



// 测试程序
int test_avl_tree(){
    auto tree = new AVLTree<int>();
    vector<int> nums = {3,2,1,4,5,6,7,16,15,14,13,12,11,10,8,9};
    for(auto i: nums){
        tree->insert(i);
    }
    cout << " preOrder:" << endl;
    tree->print();
    cout << "==高度:" << tree->get_height() << endl;
    cout << "==最小值" << tree->minimum() << endl;
    cout << "==最大值" << tree->maximum() << endl;
    cout << tree->search(15)->key << endl;
    return 0;
}
posted @ 2018-08-21 13:40  一条图图犬  阅读(307)  评论(0编辑  收藏  举报